Test instructions: There are n rings, some of which have been buckled together, now to open as few rings as possible so that all the rings can form a chain.
Analysis: At the beginning of the time, it is really not ah .... Now a bit of thinking, but still close, the method is not good enough, and finally refer to the online solution, the Great God code is not the same,
But I still read it for a long time before I read it. The first is to use the binary method of violence, because n Max is 15, will not time out, and then in the violence when the judge opened these rings, the rest is not still exist ring,
If it does not work, then it is not possible to determine whether there are two branches above the ring, because a ring if the chain is up to only two branches, so more than two is wrong, and finally,
Also to determine whether the open ring is enough, what meaning? You want to Ah, if you open the ring only 2, also need to connect the fragment ring has 3, then exactly, can use these two rings to string together,
But the fragment ring more than 3, then it is not enough, there are a few are not even up, so also to meet this condition, open the number of rings greater than or equal to need to join the fragment minus 1. The rest is how to judge
Looping and branches greater than two, first say how to determine how to calculate the branch is greater than two, in the event of violence, can be calculated separately except to open the ring and the number of rings connected to it, if more than 2,
Then is the branch is greater than 2, and how to judge the ring, it is clear that with Dfs, from a ring, see if can be searched back, if so is a ring, and finally calculate, how many rings opened,
This is the simplest is a separate violence, find a plus 1, the final calculation, of course, you can use recursion + bit operation, is a number of binary in the number of 1, you can use the bitwise and to calculate.
But my code efficiency is not high, 210ms, a little slow ...
The code is as follows:
#include <iostream> #include <cstdio> #include <cstring>using namespace Std;const int maxn = + 5;int N, Num;int G[MAXN][MAXN], Vis[maxn];bool branch (int s) {//Find branch is how many for (int i = 0; i < n; ++i) {if (S & (1<& lt;i)) continue;//to open the ring int cnt = 0; for (int j = 0; J < N; ++j) {if (S & (1<<J)) continue;//This is the ring to open, cannot evaluate if (G[i][j]) ++cnt;/ /If other rings are connected, add 1} if (CNT > 2) return true;//if greater than 2, direct end} return false; BOOL Dfs (int s, int now, int fa) {//now denotes which of the current rings, FA indicates which of the previous rings, because you cannot search yourself vis[now] = 1; for (int i = 0; i < n; ++i) {if ((S & (1<<i)) | |! G[now][i] | | i = = FA) continue;//If it is an open ring or is not connected or is itself, skip the IF (Vis[i] | | DFS (s, I, now)) return true;//If you have ever visited, that is, to find back. Or have a ring, directly return} return false;} BOOL Circle (int s) {///Determine if there is a ring for (int i = 0; i < n; ++i) {if ((S & (1<<i) | | vis[i]) continue;//is open Ring or a ring ++num that has been visited; If (Dfs (s, I,-1)) Return true;//If there is a ring directly return} return false; int cal (int s) {return s = = 0? 0:cal (S/2) + (s&1); }//calculates the number of rings to open int solve () {int ans = n-1;//is open n-1 for (int i = 0; i < (1 << n); ++i) {memset (Vis, 0, sizeof (VIS)); num = 0; if (branch (i) | | circle (i)) continue;//if there is a ring or if the branch is greater than 2 if (Cal (i) >= num-1) ans = min (ans, cal (i));//If you can connect, update a NS} return ans; int main () {//Freopen ("In.txt", "R", stdin); int kase = 0; while (scanf ("%d", &n) = = 1 && n) {int u, v; memset (g, 0, sizeof (g)); while (scanf ("%d%d", &u, &v) = = 2 && u+v > 0) {G[u-1][v-1] = 1; G[V-1][U-1] = 1; } printf ("Set%d:minimum links to Open is%d\n", ++kase, Solve ()); } return 0;}
UVa 818Cutting Chains (brute force dfs+ bit arithmetic + binary method)