poj1417
2015-10-02 16:31
260 查看
并查集+dp,一切尽在代码中。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
。
参考链接:http://blog.csdn.net/shahdza/article/details/7779230
(今天,队友买的核桃到了,帮忙带了一斤,超级好吃,我以为队友沉浸在核桃的美味中了,结果队友说她在思考,好尴尬
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/shy.gif)
)
2015.10.5:
核桃快吃完了。
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/laugh.gif)
。
参考链接:http://blog.csdn.net/shahdza/article/details/7779230
(今天,队友买的核桃到了,帮忙带了一斤,超级好吃,我以为队友沉浸在核桃的美味中了,结果队友说她在思考,好尴尬
![](http://static.blog.csdn.net/xheditor/xheditor_emot/default/shy.gif)
)
2015.10.5:
核桃快吃完了。
#include<stdio.h> #include<string.h> #include<iostream> using namespace std; #define N 1210//p1,p2分别小于300 int fa[2*N]; int cou ; int dp ; int fro ; int mark ; int get_root(int x){ if(fa[x]==x){ return x; } else{ fa[x]=get_root(fa[x]); return fa[x]; } } int main(){ int n,p1,p2; int m; int x,y; char reply[10]; while(scanf("%d%d%d",&n,&p1,&p2)!=EOF&&!(n==0&&p1==0&&p2==0)){ m=p1+p2; for(int i=1;i<=m;i++){//分清n和m的含义 fa[i]=i; cou[i]=1; } for(int i=m+1;i<=2*m;i++){ fa[i]=i; cou[i]=0; } for(int i=0;i<n;i++){ scanf("%d%d%s",&x,&y,reply); int ra=get_root(x); int ram=get_root(x+m); int rb=get_root(y); int rbm=get_root(y+m); if(reply[0]=='y'&&ra!=rb){ fa[ra]=rb; fa[ram]=rbm; cou[rb]+=cou[ra]; cou[ra]=0; cou[rbm]+=cou[ram]; cou[ram]=0; } else if(reply[0]=='n'&&ram!=rb){ fa[ra]=rbm; fa[ram]=rb; cou[rbm]+=cou[ra]; cou[ra]=0; cou[rb]+=cou[ram]; cou[ram]=0; } } /*int cou=0;//样例3错了,说明即使最后剩了不只两个集合,也可能正确的推出好人和坏人 int fcou=0,fnum=-1; int scou=0,snum=-1; bool pd=true; for(int i=1;i<=m;i++){ int rt=get_root(i); if(cou==0){ fnum=rt; fcou++; cou++; } else if(cou==1){ if(fnum==rt){ fcou++; } else{ snum=rt; scou++; cou++; } } else if(cou==2){ if(fnum==rt){ fcou++; } else if(snum==rt){ scou++; } else{ pd=false; break; } } } if(pd==false||p1==p2){ printf("no\n"); } else{ int num; if(fcou==p1){ num=fnum; } else{ num=snum; } for(int i=1;i<=m;i++){ int rt=get_root(i); if(rt==num){ printf("%d\n",i); p1--; } } printf("end\n"); }*/ memset(dp,0,sizeof(dp)); dp[0][0]=1; int froloca=0; for(int i=1;i<=m;i++){ if(cou[i]==0/*&&cou[i+m]==0*/){//如果cou[i]==0,那么cou[i+m]==0,代表i所在的组不用i来表示 continue; } else{ for(int j=0;j<=m;j++){ if(dp[froloca][j]){ dp[i][j+cou[i]]+=dp[froloca][j]; dp[i][j+cou[i+m]]+=dp[froloca][j]; fro[i][j+cou[i]]=i; fro[i][j+cou[i+m]]=i+m; } //printf("%d %d %d %d %d %dha\n",i,j+cou[i],j+cou[i+m],dp[froloca][j],i,i+m); //printf("%d %d %dhe\n",i,j+cou[i],fro[i][j+cou[i]]); //printf("%d %d %dhe\n",i,j+cou[i+m],fro[i][j+cou[i+m]]); } froloca=i; } } /*for(int i=1;i<=m;i++){ printf("%d %d\n",get_root(i),get_root(i+n)); }*/ //printf("%d\n",dp[m][p1]); /*for(int i=0;i<=m;i++){ for(int j=0;j<=m;j++){ printf("%d ",dp[i][j]); } printf("\n"); }*/ if(dp[froloca][p1]!=1){ printf("no\n"); } else{ memset(mark,false,sizeof(mark)); int fronum=p1; for(int i=froloca;i>0;i--){ if(cou[i]==0/*&&cou[i+m]==0*/){ continue; } else{ //printf("%d %d %d %dha\n",fronum,fro[i][fronum],cou[fro[i][fronum]],p1); mark[fro[i][fronum]]=true; //printf("%d\n",fro[i][fronum]); fronum=fronum-cou[fro[i][fronum]]; //printf("%dhe\n",fronum); //printf("%dha\n",fronum); } } /*for(int i=1;i<=m;i++){ if(mark[i]){ printf("%dha\n",i); } }*/ for(int i=1;i<=m;i++){ int rt=get_root(i); //printf("%d %d %d\n",i,rt,cou[i]); if(mark[rt]){ printf("%d\n",i); } } printf("end\n"); } } return 0; }
相关文章推荐
- poj1417
- HashSet的实现原理分析
- sublime text 3创建新文件插件-AdvanceNewFile
- 把不是镂空图的图片 转化成 镂空图
- ios申请真机调试( xcode 5)详细解析
- iOS 远程推送
- C语言之关键字、宏定义、条件编译
- 淘宝前端工程师:国内WEB前端开发十日谈
- jasperReport生成html图片显示问题
- Non-negative Partial Sums(单调队列,好题)
- pat1006Sign In and Sign Out (25)
- hdu 3336 Count the string(★)
- C#方法参数--值参数,引用参数,输出参数
- ocp-36
- HashMap实现原理分析
- ocp-35
- 用STC12C5A60S2的P4接口点亮LED
- JAVA设计模式之工厂模式
- lua userdata
- CodeForces 416C Booking System