http://poj.org/problem?id=3710
(To tell the truth for the Tarjan algorithm in the graph theory when do not understand, later have to find time to understand)
(The following information about the no-map-cut game comes from the paper Jia Zhihao, "a brief discussion on the combination game--on the development and transformation of the SG game")
First of all, for the non-graph of the cut-edge game has the following theorem properties:
1.(Fushion principle theorem) we can make the following changes to the graph: any one of the even rings in the graph is shrunk to a new point, and any odd ring is shrunk to a new point plus a new edge; all edges connected to the original ring are replaced with the new point. This change does not affect the SG value of the graph.
2. (1) for the odd length of the ring, remove any one of the edges, the remaining two chain length with parity, or after the SG value is unlikely to be odd, so its SG value is 1;
(2) for an even-length ring, remove any one of the edges, the remaining two chain length of the odd even, or after the SG value cannot be 0, so its SG value is 0;
3. For the pruning game of the tree, there are the following theorems:
The SG value of the leaf node is 0, and the SG value of the intermediate node is the XOR of all its child nodes after the SG value +1 .
So for this problem, using the Tarjan algorithm of the connected graph to find the ring, then delete the ring, become a simple tree, then the NIM calculation can be.
The AC code is as follows:
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<vector>using namespaceStd;vector<int> edge[ the];//adjacency Tableintbelong[ the][ the];//number of storage edgesintlow[ the],dfn[ the];ints[ the],top;//StackBOOLinstack[ the];BOOLvis[ the];//to mark unwanted pointsvoidTarjan (intUintPreintdepth) {Low[u]=dfn[u]=depth;//depth is a time stamp, the levels[top++]=u; Instack[u]=true; for(intI=0; I<edge[u].size (); i++) { intv=Edge[u][i]; if(v==pre&&belong[u][v]>1)//Judging heavy edges { if(belong[u][v]%2==0)//even ringvis[u]=true; Continue; } if(!Dfn[v]) {Tarjan (v,u,depth+1); Low[u]=min (low[u],low[v]); } Else if(v!=pre&&Instack[v]) Low[u]=min (low[u],dfn[v]); } if(dfn[u]==Low[u]) { intCnt=1; Top--; while(s[top]!=u) {vis[s[top--]]=true; CNT++; } if(cnt&& (cnt&1))//If the node is odd, keep two points plus one edgevis[s[top+1]]=false; }}intGETSG (intUintpre) { intres=0; for(intI=0; I<edge[u].size (); i++) { intv=Edge[u][i]; Res^= (GETSG (v,u) +1); //leaf node sg=0, all of its child nodes are sg+1 after an XOR or } returnRes;}voidInitintm) { for(intI=1; i<=m;i++) edge[i].clear (); Memset (Belong,0,sizeof(belong)); memset (Low,0,sizeof(low)); memset (DFN,0,sizeof(DFN)); memset (Instack,0,sizeof(Instack)); memset (Vis,0,sizeof(VIS)); Top=0;}voidAdd_edge (intUintv) {Belong[u][v]++; Belong[v][u]++; Edge[u].push_back (v); Edge[v].push_back (u);}intMain () {intn,m,k; while(~SCANF ("%d",&N)) {intres=0; while(n--) {scanf ("%d%d",&m,&k); Init (m); while(k--) { intu,v; scanf ("%d%d",&u,&v); Add_edge (U,V); } Tarjan (1,-1,1); Res^=GETSG (1,-1); } if(res) printf ("sally\n"); Elseprintf"harry\n"); } return 0;}
POJ 3710 Christmas game# Classic Chart SG game