很显然是网络流,对于点的限制,拆点建流量为1的边,之后跑最小费用最大流即可(由此很显然可以发现原图边的流量也只需要1)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 405 4 struct ji{ 5 int nex,to,len,cost; 6 }edge[N*N]; 7 queue<int>q; 8 int E,n,m,x,y,z,ans1,ans2,head[N],d[N],from[N],vis[N]; 9 void add(int x,int y,int z,int w){ 10 edge[E].nex=head[x]; 11 edge[E].to=y; 12 edge[E].len=z; 13 edge[E].cost=w; 14 head[x]=E++; 15 if (E&1)add(y,x,0,-w); 16 } 17 bool spfa(){ 18 memset(d,0x3f,sizeof(d)); 19 memset(vis,0,sizeof(vis)); 20 q.push(1); 21 d[1]=0; 22 while (!q.empty()){ 23 int k=q.front(); 24 q.pop(); 25 vis[k]=0; 26 for(int i=head[k];i!=-1;i=edge[i].nex){ 27 int v=edge[i].to; 28 if ((edge[i].len)&&(d[v]>d[k]+edge[i].cost)){ 29 d[v]=d[k]+edge[i].cost; 30 from[v]=i; 31 if (!vis[v]){ 32 vis[v]=1; 33 q.push(v); 34 } 35 } 36 } 37 } 38 return d[2*n]<0x3f3f3f3f; 39 } 40 int main(){ 41 scanf("%d%d",&n,&m); 42 memset(head,-1,sizeof(head)); 43 for(int i=1;i<=m;i++){ 44 scanf("%d%d%d",&x,&y,&z); 45 add(x,y+n,1,z); 46 } 47 for(int i=1;i<=n;i++)add(i+n,i,1,0); 48 ans1=ans2=0; 49 while (spfa()){ 50 ans1++; 51 ans2+=d[2*n]; 52 for(int i=2*n;i>1;i=edge[from[i]^1].to){ 53 edge[from[i]].len--; 54 edge[from[i]^1].len++; 55 } 56 } 57 printf("%d %d",ans1,ans2); 58 }
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11830699.html
时间: 2024-11-05 19:03:44