Uva-1627-Team them up!

来源:互联网 发布:人工蜂群算法不足 编辑:程序博客网 时间:2024/06/06 04:10

这个题最开始打算是暴力的,结果发现不行。后来想DP的(看了白书上面的讲解),把不相互认识的人另外建图,然后求连通分量,转成01背包问题。输出的时候有点恶心,需要反着推回去

代码:

#include<cstdio>#include<cstring>#include<iostream>#include<vector>#include<cmath>using namespace std;const int inf=1<<29;const int maxn=110;const int maxm=maxn*2;int n,s[maxn][maxn],color[maxn],cnt[maxn][2],grp[maxn],ind;vector<int> g[maxn],ans[2];bool dp[maxn][maxn*2];void Init(){    memset(s,0,sizeof(s));    memset(color,-1,sizeof(color));    memset(cnt,0,sizeof(cnt));    memset(dp,0,sizeof(dp));    for(int i=1;i<=n;i++)        g[i].clear();    ans[0].clear();ans[1].clear();}bool DFS(int u){    for(int i=0;i<g[u].size();i++)    {        if(color[g[u][i]]==-1)        {            grp[g[u][i]]=ind;            color[g[u][i]]=1-color[u];            cnt[ind][1-color[u]]++;            if(!DFS(g[u][i]))                return false;        }        else if(color[g[u][i]]==color[u])            return false;    }    return true;}void solve(){    dp[0][100]=1;    for(int i=1;i<=ind;i++)        for(int j=0;j<maxm;j++)            if(dp[i-1][j])            {                dp[i][j+cnt[i][0]-cnt[i][1]]=1;                dp[i][j+cnt[i][1]-cnt[i][0]]=1;            }    int l=inf,r=inf;    for(int i=100;i<maxn;i++)        if(dp[ind][i])        {            r=i;            break;        }    for(int i=100;i>=0;i--)        if(dp[ind][i])        {            l=i;            break;        }    int now=0,snow=ind-1;    if(abs(l-100)<=abs(r-100))        now=l;    else        now=r;    while(snow>=0)    {        for(int i=0;i<maxm;i++)            if(dp[snow][i])            {                if(i+cnt[snow+1][0]-cnt[snow+1][1]==now)                {                    for(int j=1;j<=n;j++)                        if(grp[j]==snow+1)                        {                            if(color[j]==0)                                ans[0].push_back(j);                            else                                ans[1].push_back(j);                        }                    now=i;                    break;                }                if(i+cnt[snow+1][1]-cnt[snow+1][0]==now)                {                    for(int j=1;j<=n;j++)                        if(grp[j]==snow+1)                        {                            if(color[j]==0)                                ans[1].push_back(j);                            else                                ans[0].push_back(j);                        }                                        now=i;                    break;                }            }        snow--;    }    for(int i=0;i<2;i++)    {        printf("%d",ans[i].size());        for(int j=0;j<ans[i].size();j++)            printf(" %d",ans[i][j]);        printf("\n");    }}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        Init();        for(int i=1;i<=n;i++)        {            while(1)            {                int v;                scanf("%d",&v);                if(!v)                    break;                s[i][v]=1;            }        }        for(int i=1;i<=n;i++)            for(int j=1;j<i;j++)                if(!s[i][j]||!s[j][i])                {                    g[i].push_back(j);                    g[j].push_back(i);                }        bool is=false;        ind=0;        for(int i=1;i<=n;i++)            if(color[i]==-1)            {                color[i]=0;                cnt[++ind][0]++;                grp[i]=ind;                if(!DFS(i))                {                    is=true;                    break;                }            }        if(is)            printf("No solution\n");        else            solve();        if(T)            printf("\n");    }    return 0;}


0 0
原创粉丝点击