费用流 建图时额外添加一个点A(左->A:(1,0) A->T:(inf,0))来保证满流 边少点多较快 边多的情况下表现很差

 1 #include<cstdio> 
 2 #include<cstring>
 3 #include<cmath>
 4 #include<ctime>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<queue>
 8 #include<set>
 9 #define inf (1ll<<(61ll))
10 #define l(a) ((a)<<1)
11 #define r(a) ((a)<<1|1)
12 #define b(a) (1<<(a))
13 #define rep(i,a,b) for(int i=a;i<=(b);i++)
14 #define clr(a) memset(a,0,sizeof(a))
15 typedef long long ll;
16 using namespace std;
17 int readint(){
18     int t=0,f=1;char c=getchar();
19     while(!isdigit(c)){
20         if(c=='-') f=-1;
21         c=getchar();
22     }
23     while(isdigit(c)){
24         t=(t<<3)+(t<<1)+c-'0';
25         c=getchar();
26     }
27     return t*f;
28 }
29 const int maxn=1009,maxe=400009;
30 int n,m,en,S,A,T;
31 ll d[maxn];
32 ll ans;
33 struct edge{
34     ll v,w,c;
35     edge*next,*r;
36 }E[maxe],*pt=E,*fir[maxn],*cur[maxn],*rev[maxn];
37 void add(int u,int v,int w,int c){
38     pt->v=v;pt->w=w;pt->c=c;
39     pt->next=fir[u];fir[u]=pt++;
40 }
41 void addedge(int u,int v,int w,int c){
42     add(u,v,w,c);add(v,u,0,-c);
43     fir[u]->r=fir[v];fir[v]->r=fir[u];
44 }
45 bool p[maxn];
46 ll spfa(){
47     queue<int>Q;clr(p);
48     rep(i,S,T) d[i]=-inf;
49     Q.push(S);p[S]=1;d[S]=0;
50     while(!Q.empty()){
51         int x=Q.front();Q.pop();p[x]=0;
52         for(edge*e=fir[x];e;e=e->next) if(e->w){
53             if(d[e->v]<d[x]+e->c){
54                 d[e->v]=d[x]+e->c;
55                 rev[e->v]=e;
56                 if(!p[e->v]){
57                     Q.push(e->v);p[e->v]=1;
58                 }
59             }
60         }
61     }
62     if(d[T]==-inf) return 0;
63     for(edge*e=rev[T];e;e=rev[e->r->v]){
64         e->w-=1;e->r->w+=1;
65     }
66     return d[T];
67 }
68 void Cal(){
69     ll t;
70     while(t=spfa()) ans+=t;
71 }
72 int main(){
73     //freopen("#input.txt","r",stdin);
74     //freopen("#output.txt","w",stdout);
75     n=readint();m=readint();en=readint();S=0;A=n+m+1;T=A+1;
76     rep(i,1,en){
77         int U=readint(),V=readint(),C=readint();
78         addedge(U,n+V,1,C);
79     }
80     rep(i,1,n) addedge(S,i,1,0);
81     rep(i,1,m) addedge(n+i,T,1,0);
82     rep(i,1,n) addedge(i,A,1,0);addedge(A,T,1000009,0);
83     Cal();
84     cout<<ans<<endl;
85     rep(i,1,n){
86         int f=0;
87         for(edge*e=fir[i];e;e=e->next){
88             if(!e->w&&e->v!=A&&e->v!=S) f=e->v-n;
89         }
90         printf("%d",f);putchar(i==n?'\n':' ');
91     }
92     //fclose(stdin);
93     //fclose(stdout);
94     return 0;
95 }
费用流

相关文章:

  • 2022-01-07
  • 2021-12-16
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-05
  • 2021-06-10
  • 2022-12-23
猜你喜欢
  • 2021-09-20
  • 2021-11-25
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-10
相关资源
相似解决方案