AmazingCounters.com

HDU 5352 MZL's City (2015 Multi-University Training Contest 5)

题目大意:

一个地方的点和道路在M年前全部被破坏,每年可以有三个操作, 1.把与一个点X一个联通块内的一些点重建,2.连一条边,3.地震震坏一些边,每年最多能重建K个城市,问最多能建多少城市,并输出操作要让字典序最小

思路:

trivial:显然每年向当年可以建的城市连边,每年可以匹配最多K个城市,嗯,很明显的网络流思路,可这样方案数不太好输出

full:再仔细想想这就是多对一的多重匹配,跑一跑匈牙利就可以,K个城市可以拆点,当然简单的方法直接跑K次也可以(想一想为什么)

为了字典序最小,我们要尽量让后面的点匹配,所以从后往前跑匹配就可以

  1 // i love zxr
  2 #include<iostream>
  3 #include<cstdio>
  4 #include<cstring>
  5 #define maxn 10009
  6 using namespace std;
  7 int matrix[209][209];
  8 int nex[maxn],head[maxn],point[maxn],now;
  9 int mark[maxn],deg[maxn],ans[maxn];
 10 int visit[maxn],x,y,match[maxn],o,p,n,m,k,h
 11 ;
 12 void add(int x,int y)
 13 {
 14     nex[++now] = head[x];
 15     head[x] = now;
 16     point[now] = y; 
 17 }
 18 
 19 int dfs1(int k,int year)
 20 {
 21     visit[k]=1;
 22     add(year,k);
 23     for(int i=1;i<=n;i++)if(matrix[k][i]==1 && !visit[i])dfs1(i,year);
 24 }
 25 
 26 int dfs(int k)
 27 {
 28     for(int i=head[k];i;i=next[i])
 29     {
 30         int u = point[i];
 31         if(visit[u])continue;
 32         visit[u]=1;
 33         if(match[u]==-1 || dfs(match[u]))
 34         {
 35             match[u] = k;
 36             return 1;
 37         }
 38     }
 39     return 0;
 40 }
 41 int main()
 42 {
 43     int t;
 44     scanf("%d",&t);
 45     while(t--)
 46     {
 47         h=0;
 48         memset(matrix,0,sizeof(matrix));
 49         memset(head,0,sizeof(head));
 50         memset(mark,0,sizeof(mark));
 51         now=0;
 52         scanf("%d%d%d",&n,&m,&k);
 53         for(int i=1;i<=m;i++)
 54         {
 55             scanf("%d",&o);
 56             if(o==1)
 57             {
 58                 scanf("%d",&x);
 59                 memset(visit,0,sizeof(visit));
 60                 dfs1(x,i);
 61                 mark[i]=1;
 62             }
 63             if(o==2)
 64             {
 65                 scanf("%d%d",&x,&y);
 66                 matrix[x][y] = 1;
 67                 matrix[y][x] = 1;
 68             }
 69             if(o==3)
 70             {
 71                 scanf("%d",&p);
 72                 for(int i=1;i<=p;i++)
 73                 {
 74                     scanf("%d%d", &x, &y);
 75                     matrix[x][y] = 0;
 76                     matrix[y][x] = 0;
 77                 }
 78             }
 79         }
 80         int an=0;
 81         memset(match,-1,sizeof(match));
 82         for(int i=m;i>=1;i--)if(mark[i])
 83         {
 84             int u =0;
 85             for(int j=1;j<=k;j++)
 86             {
 87                 memset(visit,0,sizeof(visit));
 88                 if(dfs(i))u++;
 89             }
 90             an+=u;
 91             ans[++h]=u;
 92         }
 93         printf("%d\n",an); 
 94         for(int i=h;i>=2;i--)
 95         {
 96             printf("%d ",ans[i]);
 97         }
 98         if(h)printf("%d\n",ans[1]);
 99     }
100     return 0;
101 }

 

posted @ 2015-08-04 23:23  philippica  阅读(237)  评论(0编辑  收藏  举报