日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Rochambeau POJ - 2912 (枚举和加权并查集+路径压缩)找唯一裁判

發(fā)布時(shí)間:2023/12/4 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Rochambeau POJ - 2912 (枚举和加权并查集+路径压缩)找唯一裁判 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
題意:有n個(gè)人玩石頭剪刀布,有且只有一個(gè)裁判。除了裁判每個(gè)人的出拳形式都是一樣的。 a<b表示b打敗a,a=b表示a和b出拳一樣,平手。a>b表示a打敗b。 給出m個(gè)回合的游戲結(jié)果,問能否判斷出誰是裁判?如果能還要輸出是在哪個(gè)回合之后判斷出誰是裁判。分析:枚舉和加權(quán)并查集+路徑壓縮。 對于每個(gè)人假設(shè)其為裁判,然后去掉所有和他有關(guān)的匹配,判斷是否會出現(xiàn)矛盾。 w[i]=0:i和根節(jié)點(diǎn)屬于同一集合;w[i]=1:根節(jié)點(diǎn)打敗i;w[i]=2:i打敗根節(jié)點(diǎn) 在尋找根節(jié)點(diǎn)的find()函數(shù)中,w的更新函數(shù)是:w[x]=(w[x]+w[s[x]])%3; 舉個(gè)例子:找到根節(jié)點(diǎn)之前w[x]=1,val[s[x]]=2:表示父節(jié)點(diǎn)打敗x,父節(jié)點(diǎn)也打敗父節(jié)點(diǎn)的父節(jié)點(diǎn)。 (注意此時(shí)w[x]是x與父節(jié)點(diǎn)的關(guān)系) 所以按照遞歸的思路,從遞歸倒數(shù)第二層開始s[x]就表示為根節(jié)點(diǎn)了,那么pre[x]打敗根節(jié)點(diǎn)。 又因?yàn)閟[x]也打敗x所以w[x]=0=(1+2)%3;遞歸在往上一層時(shí)pre[x]又表示為根節(jié)點(diǎn)了。 再來看看合并操作時(shí)的w關(guān)系。 fa,fb分別為aa,bb的根節(jié)點(diǎn),ww是aa與bb的關(guān)系。 當(dāng)fa!=fb時(shí),令s[fa]=fb. 假設(shè)w[aa]=1,即fa打敗aa①,w[bb]=2,即bb打敗fb②,ww=1,即bb打敗aa③。 則由②③的aa和fb是同一集合。再由①得fa打敗fb。即w[fa]=2. 也就是w[fa]=(w[bb]-w[aa]+ww)%3, 但是由于有可能w[bb]-w[aa]+ww<0,所以正確的方程是:w[fa]=(w[bb]-w[aa]+ww+3)%3, 當(dāng)fa==fb時(shí),那么就要判斷是否出現(xiàn)矛盾,如果出現(xiàn)矛盾那么說明i不能作為裁判。 判斷矛盾是:(w[aa]-w[bb]+3)%3和ww是否相等。 如果不矛盾,那么就接著讀入輸入到最后。 還要注意一點(diǎn)就是可能會出現(xiàn)多個(gè)裁判,那就是Can not determine。

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 0

Sample 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個(gè)人中有且只有一個(gè)裁判,每次枚舉一個(gè)人不參與出拳,看是否出現(xiàn)矛盾,若有,

則有且只有m-1次出現(xiàn)矛盾才能找到裁判。

AC代碼分步詳細(xì)分解

#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é)點(diǎn)s[x] int w[M];///w[x]兩節(jié)點(diǎn)的關(guān)系權(quán)值0,1,2,表示x和根節(jié)點(diǎn)的關(guān)系 int dp[M];///記錄出現(xiàn)矛盾的行數(shù) int n,m; int Find(int x)/*找到x的父節(jié)點(diǎn)*/ {if(x==s[x])return x;int temp=s[x];s[x]=Find(temp);w[x]=(w[x]+w[temp])%3; ///回溯更新與父節(jié)點(diǎn)的關(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++)///枚舉每個(gè)人{(lán)memset(w,0,sizeof(w));for(int i=0; i<n; ++i)s[i]=i;//注意這里要初始化,因?yàn)槊看谓⒌年P(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é)點(diǎn)if(fx!=fy)///如果兩個(gè)節(jié)點(diǎn)的boss不是一個(gè)人,那么就要建立關(guān)系。{/**起始w均為零,則k的關(guān)系,即為u,v之間的關(guān)系*/s[fy]=fx; /**單純表示連通,fx(u的父節(jié)點(diǎn))放在左子樹上,fy(v的父節(jié)點(diǎn))為根,u的父節(jié)點(diǎn)與v的父節(jié)點(diǎn)關(guān)系由w[fy]記錄*/w[fy]=(w[u]+k+3-w[v])%3;///(w[u]表示父節(jié)點(diǎn)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///如果兩個(gè)節(jié)點(diǎn)boss相同就要考慮ab的關(guān)系權(quán)值是否與節(jié)點(diǎn)間原來的關(guān)系權(quán)值是一樣的,如果不一樣,那么這個(gè)人就不是裁判,同時(shí)記錄下錯(cuò)是錯(cuò)在第多少組數(shù)據(jù){if((w[v]+3-w[u])%3!=k)//出現(xiàn)矛盾{dp[i]=j;//標(biāo)記出現(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]);///判斷邊最大的矛盾邊(即此時(shí)才可以保證當(dāng)枚舉去除任何一個(gè)人,都可以發(fā)現(xiàn)矛盾)}if(!cnt)printf("Impossible\n");else if(cnt>1)printf("Can not determine\n");else if(cnt==1)/**即當(dāng)枚舉去除裁判,有且只有當(dāng)去除真正的裁判,才不會發(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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。