一些二分匹配的题

/*poj1469简单的二分匹配*/



#include<stdio.h>

#include<string.h>

int map[1005][1005],vis[2000],match[2000];

int n,m;

int dfs(int u)

{

    int i,j;

    for(i=1;i<=n;i++)//根据课

    {

        if(!vis[i]&&map[u][i])

        {

            vis[i]=1;

            if(match[i]==-1||dfs(match[i]))

            {

                match[i]=u;

                return 1;

            }

        }

    }

    return 0;

}

int main()

{

    int i,j,t;

    scanf("%d",&t);

    while(t--)

    {

        memset(map,0,sizeof(map));

        scanf("%d%d",&m,&n);//m人 n课

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

        {

            int l,x;

            scanf("%d",&l);

            while(l--)

            {

                scanf("%d",&x);

                map[i][x]=1;

            }

        }

        int ans=0;

        memset(match,-1,sizeof(match));

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

        {

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

            if(dfs(i))

                ans++;

        }

        if(ans==m)

            printf("YES\n");

        else printf("NO\n");

    }

}








/**poj2446*/ /*第一次交数组开小了 ,改好就A了,哈哈,开心*/ #include<stdio.h> #include<string.h> int map[50][50],g[1205][1205],n,m,k,sum,vis[3000],match[3000]; void makemap() { memset(g,0,sizeof(g)); int i,j; for(i=1;i<=n;i++) { for(j=1;j<=m;j++) { if(map[i][j]&&(i+1)<=n) g[map[i][j]][map[i+1][j]]=1;//下面的 if(map[i][j]&&(i-1)>=1) g[map[i][j]][map[i-1][j]]=1;//上面的 if(map[i][j]&&(j+1)<=m) g[map[i][j]][map[i][j+1]]=1;//右面的 if(map[i][j]&&(j-1)>=1) g[map[i][j]][map[i][j-1]]=1;//左面的 } } } int dfs(int u) { int i,j; for(i=1;i<sum;i++) { if(g[u][i]&&!vis[i]) { vis[i]=1; if(match[i]==-1||dfs(match[i])) { match[i]=u; return 1; } } } return 0; } int main() { int i,j; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { sum=1; for(i=1;i<=n;i++) for(j=1;j<=m;j++) map[i][j]=sum++; for(i=1;i<=k;i++) { int x,y; scanf("%d%d",&x,&y); map[y][x]=0; } makemap(); int ans=0; memset(match,-1,sizeof(match)); for(i=1;i<sum;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) { ans++; } } if(ans+k==(n*m)) printf("YES\n"); else printf("NO\n"); } }
//最大独立集

//hdu1068

#include<stdio.h>

#include<string.h>

struct node

{

    int x;

    int next;

}edge[2000];

int head[2000],n,vis[2000],match[2000];

int index;

void add(int xx,int yy)

{

    edge[index].x=yy;

    edge[index].next=head[xx];

    head[xx]=index++;

}

int dfs(int u)

{

    int i,j;

    for(i=head[u];i!=-1;i=edge[i].next)

    {

        int tmp=edge[i].x;

        if(!vis[tmp])

        {

            vis[tmp]=1;

            if(match[tmp]==-1||dfs(match[tmp]))

            {

                match[tmp]=u;

                return 1;

            }

        }

    }

    return 0;

}

int main()

{

    int i,j,t;

    while(scanf("%d",&n)!=EOF)

    {

        memset(head,-1,sizeof(head));

        memset(match,-1,sizeof(match));

        index=0;

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

        {

            scanf("%d: (%d)",&j,&t);

            while(t--)

            {

                int l;

                scanf("%d",&l);

                add(j,l);

            }

        }

        int ans=0;

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

        {

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

            if(dfs(i))

                ans++;

        }

        if(ans%2)ans+=1;

        printf("%d\n",n-ans/2);//最大独立集=顶点总数-二分图最大匹配

    }

}











/*

最小顶点覆盖 == 最大匹配(双向图)/2;
hdu1054 要双向图
*/ #include<stdio.h> #include<string.h> struct node { int v; int next; }edge[20000]; int vis[2000],head[2000],match[2000]; int n,m,index; void add(int x,int y) { edge[index].v=y; edge[index].next=head[x]; head[x]=index++; } int dfs(int u) { int i,j; for(i=head[u];i!=-1;i=edge[i].next) { int tmp=edge[i].v; if(!vis[tmp]) { vis[tmp]=1; if(match[tmp]==-1||dfs(match[tmp])) { match[tmp]=u; return 1; } } } return 0; } int main() { int i,j,t; while(scanf("%d",&n)!=EOF) { index=1; memset(head,-1,sizeof(head)); memset(match,-1,sizeof(match)); for(i=0;i<n;i++) { int l; scanf("%d:(%d)",&l,&t); while(t--) { int x; scanf("%d",&x); add(l,x); add(x,l); } } int ans=0; for(i=0;i<n;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) { ans++; } } printf("%d\n",ans/2); } }
hdu2119
建图发现同一行和同一列能够消除; 然后可以发现就是从这一点出发,同一行,同一列有1的点就能够连接起来; 然后就是一张2分图;
0 0 0 1 0 1 0 1 0 二分图 :2->1,2->3,3->2; /**hdu2119**/ //建图的重要性,把行和列作为图来写 #include<stdio.h> #include<string.h> int map[200][200]; int n,m; int vis[10005],match[10005],index; int dfs(int u) { int i,j; for(i=1;i<=m;i++) { if(!vis[i]&&map[u][i]==1) { vis[i]=1; if(match[i]==-1||dfs(match[i])) { match[i]=u; return 1; } } } return 0; } int main() { int i,j; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0)break; memset(match,-1,sizeof(match)); memset(map,0,sizeof(map)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&map[i][j]); } int ans=0; for(i=1;i<=n;i++) { memset(vis,0,sizeof(vis)); if(dfs(i)) ans++; } printf("%d\n",ans); } }

 

 

 1 //hdu5090 二分匹配

 2 #include<stdio.h>

 3 #include<string.h>

 4 int match[103],vis[103];

 5 int map[103][103];

 6 int n,k;

 7 int dfs(int u)

 8 {

 9     int i,j;

10     for(i=1;i<=n;i++)

11     {

12         if(!vis[i]&&map[u][i])

13         {

14             vis[i]=1;

15             if(match[i]==-1||dfs(match[i]))

16             {

17                 match[i]=u;

18                 return 1;

19             }

20         }

21     }

22     return 0;

23 }

24 int main()

25 {

26     int i,j;

27     int t;

28     scanf("%d",&t);

29     while(t--)

30     {

31         memset(match,-1,sizeof(match));

32         memset(map,0,sizeof(map));

33         scanf("%d%d",&n,&k);

34         for(i=1;i<=n;i++)

35         {

36             int x;

37             scanf("%d",&x);

38             int t=x;

39             while(t<=n)

40             {

41                 map[t][i]=1;

42                 t+=k;

43             }

44         }

45         int ans=0;

46         for(i=1;i<=n;i++)

47         {

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

49             if(dfs(i))

50                 ans++;

51         }

52         if(ans==n)

53             printf("Jerry\n");

54         else printf("Tom\n");

55     }

56 }

 最感人的二分匹配题 不会建图。。

 zoj  Place the Robots

  1 #include<stdio.h>

  2 #include<string.h>

  3 char map[52][52];

  4 int g[2600][2600],n,m,match[2600];

  5 int x[52][52],y[52][52];

  6 int xx,yy;

  7 bool vis[2600];

  8 bool dfs(int u)

  9 {

 10     int i,j;

 11     for(i=1;i<=yy;i++)

 12     {

 13         if(!vis[i]&&g[u][i])

 14         {

 15             vis[i]=true;

 16             if(match[i]==-1||dfs(match[i]))

 17             {

 18                 match[i]=u;

 19                 return true;

 20             }

 21         }

 22     }

 23     return false;

 24 }

 25 int main()

 26 {

 27     int i,j,ff,t,flag;

 28     scanf("%d",&t);

 29     ff=0;

 30     while(t--)

 31     {

 32         scanf("%d%d",&n,&m);

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

 34             scanf("%s",map[i]);

 35         memset(g,0,sizeof(g));

 36         int num=0;

 37         flag=0;

 38         memset(x,0,sizeof(x));

 39         memset(y,0,sizeof(y));

 40         for(i=0;i<n;i++)//按行来

 41         {

 42             flag=0;

 43             for(j=0;j<m;j++)

 44             {

 45                 if(map[i][j]=='o')

 46                 {

 47                     if(!flag)

 48                         num++;

 49                     x[i][j]=num;flag=1;

 50                 }

 51                 else if(map[i][j]=='#')

 52                 {

 53                     flag=0;

 54                 }

 55             }

 56         }

 57         xx=num;num=0;

 58         //竖直方向

 59         for(i=0;i<m;i++)

 60         {

 61             flag=0;

 62             for(j=0;j<n;j++)

 63             {

 64                 if(map[j][i]=='o')

 65                 {

 66                     if(!flag)

 67                         num++;

 68                     y[j][i]=num;

 69                     flag=1;

 70                 }

 71                 else if(map[j][i]=='#')

 72                     flag=0;

 73             }

 74         }

 75         yy=num;

 76         //建新图

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

 78             for(j=0;j<m;j++)

 79             {

 80                 if(x[i][j])

 81                 {

 82                     g[x[i][j]][y[i][j]]=1;

 83                 }

 84             }

 85         

 86         

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

 88         {

 89             for(j=0;j<m;j++)

 90             {

 91                 printf("%d ",x[i][j]);

 92             }

 93             printf("\n");

 94         }

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

 96         {

 97             for(j=0;j<m;j++)

 98             {

 99                 printf("%d ",y[i][j]);

100             }

101             printf("\n");

102         }

103         

104             

105         //二分匹配

106         memset(match,-1,sizeof(match));

107         int ans=0;

108         for(i=1;i<=xx;i++)

109         {

110             memset(vis,false,sizeof(vis));

111             if(dfs(i))

112                 ans++;

113         }

114 

115         printf("Case :%d\n",++ff);

116         printf("%d\n",ans);

117     }

118 }

119 

120 /*

121 

122 2

123 5 5

124 o***#

125 *###*

126 oo#oo

127 ***#o

128 #o**o

129 4 4

130 o***

131 *###

132 oo#o

133 ***o

134 

135 */

 


 

你可能感兴趣的:(二分)