您的位置:首页 > 其它

poj1417

2015-10-02 16:31 260 查看
并查集+dp,一切尽在代码中。



参考链接:http://blog.csdn.net/shahdza/article/details/7779230

(今天,队友买的核桃到了,帮忙带了一斤,超级好吃,我以为队友沉浸在核桃的美味中了,结果队友说她在思考,好尴尬



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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: