您的位置:首页 > 其它

【UOJ 80】 二分图最大权匹配

2017-03-02 21:47 387 查看
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<algorithm>
6 #include<queue>
7 using namespace std;
8 #define Maxn 410
9 #define Maxm 160010
10 // #define INF 0x7fffffff
11 #define LL long long
12 const LL INF=1LL<<62;
13
14 LL mymin(LL x,LL y) {return x<y?x:y;}
15 LL mymax(LL x,LL y) {return x>y?x:y;}
16
17 int N;
18
19 int n,m;
20 int match[Maxn],op[Maxn];
21 LL eg[Maxn][Maxn],lx[Maxn],ly[Maxn],slack[Maxn];
22 int visx[Maxn],visy[Maxn],pre[Maxn];
23
24 void mh(int y)
25 {
26     for(int x,z;y>0;y=z)
27     {
28         x=pre[y];z=op[x];
29         op[x]=y;match[y]=x;
30     }
31 }
32
33 int nt;
34 void ffind(int st)
35 {
36     for(int i=1;i<=N;i++) slack[i]=INF;
37     queue<int> q;nt++;
38     q.push(st);visx[st]=nt;
39     while (1)
40     {
41         while(!q.empty())
42         {
43             int x=q.front();q.pop();
44             for(int y=1;y<=N;y++)
45              if(visy[y]!=nt)
46              {
47                  if(lx[x]+ly[y]==eg[x][y])
48                  {
49                      pre[y]=x;
50                      if(!match[y]) {mh(y);return;}
51                      q.push(match[y]);
52                      visx[match[y]]=nt;visy[y]=nt;
53                  }
54                  else if(slack[y]>lx[x]+ly[y]-eg[x][y])
55                     slack[y]=lx[x]+ly[y]-eg[x][y],pre[y]=x;
56              }
57         }
58         LL delta=INF;
59         for(int y=1;y<=N;y++) if(visy[y]!=nt) delta=mymin(delta,slack[y]);
60         for(int i=1;i<=N;i++)
61         {
62             if(visx[i]==nt) lx[i]-=delta;
63             if(visy[i]==nt) ly[i]+=delta;
64             else slack[i]-=delta;
65         }
66         for(int i=1;i<=N;i++) if(visy[i]!=nt&&slack[i]==0)
67         {
68             if(!match[i]) {mh(i);return;}
69             q.push(match[i]);
70             visx[match[i]]=nt;visy[i]=nt;
71         }
72     }
73 }
74
75
76 LL KM()
77 {
78     memset(visx,0,sizeof(visx));
79     memset(visy,0,sizeof(visy));
80     for (int i=1;i<=N;i++) lx[i]=ly[i]=0,op[i]=match[i]=0;
81     for (int i=1;i<=N;i++)
82      for (int j=1;j<=N;j++)
83       lx[i]=mymax(lx[i],eg[i][j]);
84     for (int i=1;i<=N;i++) ffind(i);
85 }
86
87 void output()
88 {
89     LL ans=0;
90     for(int i=1;i<=N;i++) ans+=lx[i]+ly[i];
91     printf("%lld\n",ans);
92     for(int i=1;i<=n;i++) if(eg[i][op[i]]!=0) printf("%d ",op[i]);
93     else printf("0 ");printf("\n");
94 }
95
96 void init()
97 {
98     int l;
99     memset(eg,0,sizeof(eg));
100     scanf("%d%d%d",&n,&m,&l);
101     for(int i=1;i<=l;i++)
102     {
103         int x,y;
104         LL c;
105         scanf("%d%d%lld",&x,&y,&c);
106         eg[x][y]=mymax(eg[x][y],c);
107     }
108     N=mymax(n,m);
109 }
110
111 int main()
112 {
113     init();
114         KM();
115     output();
116         return 0;
117 }


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: