1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define M 1000 7 #define inf 2139062143 8 using namespace std; 9 int cnt=1,n,K,m,T,q[300*M],d[M],f[M],head[M],next[300*M],u[300*M],v[300*M],w[300*M],fro[300*M],fr[M],S1,d1[M][M]; 10 int ans; 11 void jia1(int a1,int a2,int a3,int a4) 12 { 13 cnt++; 14 next[cnt]=head[a1]; 15 head[a1]=cnt; 16 fro[cnt]=a1; 17 u[cnt]=a2; 18 v[cnt]=a3; 19 w[cnt]=a4; 20 } 21 void jia(int a1,int a2,int a3,int a4) 22 { 23 jia1(a1,a2,a3,a4); 24 jia1(a2,a1,0,-a4); 25 return; 26 } 27 bool spfa() 28 { 29 memset(d,127,sizeof(int)*(T+1)); 30 d[0]=0; 31 f[0]=1; 32 q[1]=0; 33 int h=0,t=1; 34 for(;h<t;) 35 { 36 h++; 37 int p=q[h]; 38 f[p]=0; 39 for(int i=head[p];i;i=next[i]) 40 if(v[i]&&d[u[i]]>d[p]+w[i]) 41 { 42 d[u[i]]=d[p]+w[i]; 43 fr[u[i]]=i; 44 if(!f[u[i]]) 45 { 46 f[u[i]]=1; 47 t++; 48 q[t]=u[i]; 49 } 50 } 51 } 52 if(d[T]!=inf) 53 return 1; 54 return 0; 55 } 56 void mcf() 57 { 58 int mx=inf; 59 for(int i=fr[T];i;i=fr[fro[i]]) 60 mx=min(mx,v[i]); 61 for(int i=fr[T];i;i=fr[fro[i]]) 62 { 63 v[i]-=mx; 64 v[i^1]+=mx; 65 ans+=mx*w[i]; 66 } 67 return; 68 } 69 int gcd(int a1,int a2) 70 { 71 int a3=a1%a2; 72 for(;a3;) 73 { 74 a1=a2; 75 a2=a3; 76 a3=a1%a2; 77 } 78 return a2; 79 } 80 int main() 81 { 82 scanf("%d%d%d",&n,&m,&K); 83 S1=2*n+1; 84 T=2*n+2; 85 memset(d1,60,sizeof(d1)); 86 for(int i=1;i<=m;i++) 87 { 88 int a1,a2,a3; 89 scanf("%d%d%d",&a1,&a2,&a3); 90 d1[a1][a2]=min(d1[a1][a2],a3); 91 d1[a2][a1]=min(d1[a2][a1],a3); 92 } 93 for(int k=0;k<=n;k++) 94 for(int i=0;i<=n;i++) 95 for(int j=k;j<=n;j++) 96 d1[i][j]=min(d1[i][j],d1[i][k]+d1[k][j]); 97 jia(0,S1,K,0); 98 for(int i=1;i<=n;i++) 99 { 100 jia(S1,n+i,1,d1[0][i]); 101 jia(0,i,1,0); 102 jia(i+n,T,1,0); 103 for(int j=i+1;j<=n;j++) 104 jia(i,j+n,1,d1[i][j]); 105 } 106 for(;spfa();) 107 mcf(); 108 printf("%d",ans); 109 return 0; 110 }
先预处理出所有点之间的最短距离,开一个附加源S1,S到S1连一个容量为k的边,拆点S1到每个i2连容量1费用d[0][i],每个i2向T连边,每个i1向比他大的j2建边。费用流。