POJ1417 True Liars 题解

通过读题,容易发现,当回答为yes(x,y) 必属于同类,当回答为no时二者必为异类(并且当 (x=y) 时,回答必为yes,不过这题不用这个性质)。
于是先按关系维护连通块,然后求出每个连通块的人数,用背包看是否能够凑出。可以把一个连通块的看作一个物品,总共的天神数就是背包的容量。
还用了set辅助维护每个连通块里具体是哪些人。
这道题刚开始一直卡着,结果照着样例手玩一遍就全懂了,所以光空想还是不行的。
具体看丑陋的代码吧……

#include <bits/stdc++.h>
using namespace std;

const int N=1005,M=605;
struct path{int r1,r2,rd1,rd2;}p[M];
set<int> s[M<<1];
int fa[M<<1],n,m,p1,p2,d[M<<1],f[M][M];

int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]);}
void merge(int x,int y) {fa[find(x)]=find(y);}

int main()
{
    while(~scanf("%d%d%d",&n,&p1,&p2)&&(n||p1||p2))
    {
        m=p1+p2;
        for(int i=1;i<=m+m;++i) fa[i]=i,s[i].clear();
        for(int i=1,x,y;i<=n;++i)
        {
            char s[5];
            scanf("%d %d %s",&x,&y,s);
            if(s[0]=='y') merge(x,y),merge(x+m,y+m);
            else merge(x,y+m),merge(x+m,y);
        }
        memset(d,0,sizeof(d));
        for(int i=1;i<=m;++i)
        {
            int x=find(i);
            d[x]++; s[x].insert(i);
        }
        int cnt=0;
        for(int i=1;i<=m+m;++i)
        {
            if(!d[i]) continue;
            int x=i<=m?i:i-m;int y=x+m;
            x=find(x),y=find(y);
            p[++cnt].r1=d[x];
            p[cnt].r2=d[y];
            p[cnt].rd1=x,p[cnt].rd2=y;
            d[x]=d[y]=0;
        }
        memset(f,0,sizeof(f));
        f[0][0]=1;
        for(int i=1;i<=cnt;++i)
            for(int j=p1;~j;--j)
            {
                if(j>=p[i].r1) f[i][j]+=f[i-1][j-p[i].r1];
                if(j>=p[i].r2) f[i][j]+=f[i-1][j-p[i].r2];
            }
        if(f[cnt][p1]!=1) puts("no");
        else
        {
            set<int> ans; int sum=p1;
            for(int i=cnt;i;--i)
                if(f[i-1][sum-p[i].r1])
                    ans.insert(s[p[i].rd1].begin(),s[p[i].rd1].end()),sum-=p[i].r1;
                else ans.insert(s[p[i].rd2].begin(),s[p[i].rd2].end()),sum-=p[i].r2;
            for(int i : ans) printf("%d
",i);
            puts("end");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/wzzyr24/p/12268041.html