zoukankan      html  css  js  c++  java
  • poj 1112

    昨天晚上看的题。

    说实话,我一眼就看出了是二分图,再一眼就看出了是二分图+dp(01背包)。但悲剧的是我一眼看出的算法是正确的,但我总以为它是错误的,浪费了很长时间像其他算法(TAT)。

    今天终于把代码打了出来,刚开始01背包的优化后来发现是错误的,忘记删了,导致WA一次。吃晚饭时突然发现了,便AC。

    2013-6-29

    代码:

    #include<cstdio>

    #include<cstring>

    using namespace std;

    int n,col[101],w[202],m=0,dp[101][101],pre[101][101];

    bool map[101][101]={0},vis[202]={0},f=0;

    void dfs(int x,int cur){

             vis[x]=1,col[x]=2*m+cur;

             w[2*m+cur]++;

             for(int i=0;i<n;i++){

                       if(map[x][i] && vis[i] && col[x]==col[i]){

                                f=1;

                                return;

                       }

                       if(map[x][i] && !vis[i]){

                                dfs(i,1^cur);

                                if(f)return;

                       }

             }

             return;

    }

    int max(int x,int y){

             return (x>y)?x:y;

    }

    int min(int x,int y){

             return (x<y)?x:y;

    }

    int main(){

             scanf("%d",&n);

             for(int i=0;i<n;i++){

                       int x;

                       while(scanf("%d",&x),x!=0)

                                map[i][--x]=1;

             }

             for(int i=0;i<n;i++)

                       for(int j=0;j<i;j++)

                                if(map[i][j]*map[j][i]==0 && i!=j)map[i][j]=map[j][i]=1;else map[i][j]=map[j][i]=0;

             for(int i=0;i<n;i++)if(!vis[i]){

                       dfs(i,0);

                       m++;

             }

             if(f){

                       printf("No solution\n");

                       return 0;

             }

             m*=2;

             memset(dp[0],-1,sizeof(dp[0]));

             memset(vis,0,sizeof(vis));

             dp[0][0]=0;

             for(int i=1;i<=m;i+=2)

                       for(int j=0;j<=n;j++){       //这里我一开始打成了for(int j=min(w[i-1],w[i]);j<=n;j++)

                                int a=(i+1)/2;

                                dp[a][j]=-1;pre[a][j]=-1;

                                if(j>=w[i-1] && dp[a-1][j-w[i-1]]+w[i-1]>max(dp[a][j],w[i-1]-1))dp[a][j]=max(dp[a][j],dp[a-1][j-w[i-1]]+w[i-1]),pre[a][j]=2;

                                if(j>=w[i] && dp[a-1][j-w[i]]+w[i]>max(dp[a][j],w[i]-1))dp[a][j]=max(dp[a][j],dp[a-1][j-w[i]]+w[i]),pre[a][j]=1;

                       }

             int j;

             for(j=n/2;j>=0 && dp[m/2][j]==-1;j--);

             if(j<0){

                       printf("No solution\n");

                       return 0;

             }

             int j1=j;

             for(int i=m/2;i>0;i--)

                       vis[i*2-pre[i][j]]=1,j-=w[i*2-pre[i][j]];

             printf("%d",j1);

             for(int i=0;i<n;i++)

                       if(vis[col[i]])printf(" %d",i+1);

             printf("\n");

             printf("%d",n-j1);

             for(int i=0;i<n;i++)

                       if(!vis[col[i]])printf(" %d",i+1);

             printf("\n");

             return 0;

    }

  • 相关阅读:
    在Codeblocks下配置GoogleTest单元测试工具
    自制贪吃蛇游戏中的几个“大坑”
    贪吃蛇“大作战”(进阶篇)
    贪吃蛇“大作战”(终结篇)
    贪吃蛇“大作战”(六)
    贪吃蛇“大作战”(五)
    贪吃蛇“大作战”(四)
    贪吃蛇“大作战”(三)
    小心!选择的陷阱
    贪吃蛇“大作战”(二)
  • 原文地址:https://www.cnblogs.com/shanquan2/p/3165921.html
Copyright © 2011-2022 走看看