Rochambeau POJ - 2912 (枚举和加权并查集+路径压缩)找唯一裁判
N?children are playing Rochambeau (scissors-rock-cloth) game with you. One of them is the judge. The rest children are divided into three groups (it is possible that some group is empty). You don’t know who is the judge, or how the children are grouped. Then the children start playing Rochambeau game for?M?rounds. Each round two children are arbitrarily selected to play Rochambeau for one once, and you will be told the outcome while not knowing which gesture the children presented. It is known that the children in the same group would present the same gesture (hence, two children in the same group always get draw when playing) and different groups for different gestures. The judge would present gesture randomly each time, hence no one knows what gesture the judge would present. Can you guess who is the judge after after the game ends? If you can, after how many rounds can you find out the judge at the earliest?
Input
Input contains multiple test cases. Each test case starts with two integers?N?and?M?(1 ≤?N?≤ 500, 0 ≤?M?≤ 2,000) in one line, which are the number of children and the number of rounds. Following are?M?lines, each line contains two integers in [0,?N) separated by one symbol. The two integers are the IDs of the two children selected to play Rochambeau for this round. The symbol may be “=”, “>” or “<”, referring to a draw, that first child wins and that second child wins respectively.
Output
There is only one line for each test case. If the judge can be found, print the ID of the judge, and the least number of rounds after which the judge can be uniquely determined. If the judge can not be found, or the outcomes of the?M?rounds of game are inconsistent, print the corresponding message.
Sample Input
3 3 0<1 1<2 2<0 3 5 0<1 0>1 1<2 1>2 0<2 4 4 0<1 0>1 2<3 2>3 1 0Sample Output
Can not determine Player 1 can be determined to be the judge after 4 lines Impossible Player 0 can be determined to be the judge after 0 lines題意分析:簡單來說,就是,m個人中有且只有一個裁判,每次枚舉一個人不參與出拳,看是否出現(xiàn)矛盾,若有,
則有且只有m-1次出現(xiàn)矛盾才能找到裁判。
AC代碼分步詳細分解
#include<stdio.h> #include<algorithm> #include<string.h> using namespace std; #define M 500+10 #define N 2000+10 struct node///開結(jié)構(gòu)體,記錄每一行u,v和他們之間的關(guān)系k {int u,v,k; } q[N]; int s[M];///s[x]并查集記錄x的父節(jié)點s[x] int w[M];///w[x]兩節(jié)點的關(guān)系權(quán)值0,1,2,表示x和根節(jié)點的關(guān)系 int dp[M];///記錄出現(xiàn)矛盾的行數(shù) int n,m; int Find(int x)/*找到x的父節(jié)點*/ {if(x==s[x])return x;int temp=s[x];s[x]=Find(temp);w[x]=(w[x]+w[temp])%3; ///回溯更新與父節(jié)點的關(guān)系return s[x]; } int main() {while(~scanf("%d%d",&n,&m)){int i,j,k,u,v;char e;for(i=1; i<=m; ++i){scanf("%d%c%d",&q[i].u,&e,&q[i].v);if(e=='>')// y吃xq[i].k=2;else if(e=='<') // x吃yq[i].k=1;else if(e=='=') //同類q[i].k=0;}memset(dp,-1,sizeof(dp));for(i=0; i<n; i++)///枚舉每個人{memset(w,0,sizeof(w));for(int i=0; i<n; ++i)s[i]=i;//注意這里要初始化,因為每次建立的關(guān)系都有可能不一樣for(j=1; j<=m; ++j){if(q[j].u==i||q[j].v==i) ///枚舉:屏蔽裁判continue;u=q[j].u,v=q[j].v,k=q[j].k;///k為u,v之間的關(guān)系int fx=Find(u),fy=Find(v);///fx,fy分別 u,v的根節(jié)點if(fx!=fy)///如果兩個節(jié)點的boss不是一個人,那么就要建立關(guān)系。{/**起始w均為零,則k的關(guān)系,即為u,v之間的關(guān)系*/s[fy]=fx; /**單純表示連通,fx(u的父節(jié)點)放在左子樹上,fy(v的父節(jié)點)為根,u的父節(jié)點與v的父節(jié)點關(guān)系由w[fy]記錄*/w[fy]=(w[u]+k+3-w[v])%3;///(w[u]表示父節(jié)點fx與u的關(guān)系)(w[v]表示fy與v的關(guān)系)由k的值判定u與v的關(guān)系}///但是由于有可能 w[u]+k+-w[v]<0,所以正確的方程是: w[fy]=(w[u]+k+3-w[v])%3,else///如果兩個節(jié)點boss相同就要考慮ab的關(guān)系權(quán)值是否與節(jié)點間原來的關(guān)系權(quán)值是一樣的,如果不一樣,那么這個人就不是裁判,同時記錄下錯是錯在第多少組數(shù)據(jù){if((w[v]+3-w[u])%3!=k)//出現(xiàn)矛盾{dp[i]=j;//標記出現(xiàn)矛盾所在行break;}}}}int cnt=0,ans=0;for(i=0; i<n; ++i){if(dp[i]==-1)cnt++,v=i;ans=max(ans,dp[i]);///判斷邊最大的矛盾邊(即此時才可以保證當枚舉去除任何一個人,都可以發(fā)現(xiàn)矛盾)}if(!cnt)printf("Impossible\n");else if(cnt>1)printf("Can not determine\n");else if(cnt==1)/**即當枚舉去除裁判,有且只有當去除真正的裁判,才不會發(fā)生矛盾*/printf("Player %d can be determined to be the judge after %d lines\n",v,ans);}return 0; }?
總結(jié)
以上是生活随笔為你收集整理的Rochambeau POJ - 2912 (枚举和加权并查集+路径压缩)找唯一裁判的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在小程序添加外部链接
- 下一篇: 支付宝刷脸登陆怎么设置