This problem has been done for two days. The first use and check the classification is clear, but to determine whether the situation is only just beginning to use the search. Always times out. Later read the report of other people's knot, only to realize that the only way to judge the DP.
Main topic:
Altogether there are p1+p2 individuals, divided into two groups, a group of P1, a group of P2. Gives the n conditions, in the following format:
X y yes means x and Y are divided into the same group
X y no means x and Y are divided into different groups
Ask if the packet is unique, if the only one is from small to large sequential output, otherwise output No. Ensure that there are no contradictory conditions, but there is a possibility of x=y situation.
Topic Analysis: The question will give us some information, tell us those are the same class, which are different classes. Of course, at first we couldn't judge the kind of person who was good and bad. Then we might as well put the points of the relationship (whether they are a yes or no) all in one category, they have an identical parent node. It then uses an array (relation[]) to record his relationship to the parent node (0 for the same class and 1 for the heterogeneous). Of course, because only a subset of the information is given, it may not be possible to classify all points as a category (for example: 3,4 yes. Only to show that the same kind, 3,4, 1,3 relations do not know). Then you might want to set up a few different sets (with the parent node as the standard), each set divided into two categories, similar to the parent node (relation[] = 0), and different classes (relation[] = 1) from the parent node. At this point our question turns to whether the answer is unique. Take one of the types in each collection and take only one (homogeneous or non-homogeneous). See if the cumulative number of P1 is the only case.
#include <iostream>#include<cstdio>#include<string.h>using namespacestd;intN, N1, N2, MI, MX, key, flag, a[605][2], vis[605][605][2], ans[605][2], v[605], d[605][605], pre[610], relation[605];intFindintX//find the root of the Father node{ if(Pre[x] = =x)returnx; Else if(Pre[x]! =x) {intt =Pre[x]; PRE[X]= Find (pre[x]);//edge to find the root of the Father node, edge update the original Father node informationRELATION[X] = (Relation[t] + relation[x])%2;//updates similar to the kind and check set } returnpre[x];}voidWorkintAintBintC//Merging Nodes{ intFX =find (a); intFY =find (b); if(FX! =FY) {PRE[FX]=fy; RELATION[FX]= (Relation[a] + relation[b] + c)%2; }}voiddp () {intK =1; for(inti = mi+1; I <= (N1+N2); i++) { if(V[i] = =1) {k++; intT1 = ans[i][0]; intT2 = ans[i][1]; intMX =min (t1, T2); for(intj = N1; J >= MX; j--) {D[k][j]= d[k-1][J-T1] + d[k-1][j-T2]; if(d[k-1][J-T1] = =1&& d[k-1][J-T2] = =0) {vis[k][j][0] =i; vis[k][j][1] =0; } Else if(d[k-1][J-T2] = =1&& d[k-1][J-T1] = =0) {vis[k][j][0] =i; vis[k][j][1] =1; } } } }}intMain () { while(SCANF ("%d%d%d", &n, &N1, &n2)! =EOF) { if(n = =0&& N1 = =0&& N2 = =0) Break; //Initialize all nodes to parent node and relation for(inti =1; I <= n1+n2; i++) {Pre[i] = i; relation[i] =0;} for(inti =1; I <= N; i++) { intA, B; Charc[Ten]; scanf ("%d%d%s", &a, &b, &c); if(strcmp (C,"Yes") ==0) Work (A, B,0); Else if(strcmp (C,"No") ==0) Work (A, B,1); } //Note here: To this step, there may be some points of the parent node that is not the closest node for(inti =1; I <= n1+n2; i++) intt =find (i); memset (V,0,sizeof(v)); //Ans[i][0] Represents the number of nodes of the same type as the root node I, and ans[i][1] represents the number of nodes of the same class as the root node Imemset (ans,0,sizeof(ans)); Flag=0;//how many different parent nodes are storedMi =10e9; for(inti =1; I <= n1+n2; i++) { intx =Pre[i]; inty =Relation[i]; if(X <mi) Mi=x; Ans[x][y]++; if(V[x] = =0) {V[x]=1; Flag++; } } /*D[i][j] The cumulative number of people in the first I set is J, how many possibilities are there, vis[i][j][] save each set to select which class to use for the final output. Vis[i][j][0] represents the maximum number of nodes in the first set of J, Vis[i][j][1] indicates the relationship to the root node when the cumulative number of people in the first I set is J and the root node is vis[i][j][0] .*/memset (d,0,sizeof(d)); memset (Vis,0,sizeof(VIS)); d[1][ans[mi][0]]++; d[1][ans[mi][1]]++; vis[1][ans[mi][0]][0] =mi; vis[1][ans[mi][0]][1] =0; vis[1][ans[mi][1]][0] =mi; vis[1][ans[mi][1]][1] =1; DP (); if(D[flag][n1] = =1)//if the cumulative number of N1 in the previous flag collection is 1 o'clock, there is a unique solution { intj =N1; for(inti = flag; I >=1; i--)//push forward from behind{a[i][0] = vis[i][j][0]; a[i][1] = vis[i][j][1];//record which class I obtained in the collection (similar 0, different Class 1)J-= ans[a[i][0]][a[i][1]]; } for(inti =1; I <= n1+n2; i++) { for(intj =1; J <= Flag; J + +) { intf =Pre[i]; intFF =Relation[i]; if(f = = a[j][0] && ff = = a[j][1]) printf ("%d\n", i); }} printf ("end\n"); } Elseprintf ("no\n"); } return 0;}
View Code
poj1417 True Liars (and check set + DP) detailed