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建边。费用流。

posted on 2016-03-20 23:10  xiyuedong  阅读(158)  评论(0编辑  收藏  举报