题意:不多说了。
题解:
begin
首先想到:我们要强制走过那些下界。
怎么强制呢?我们把费用赋为-inf!!看他走不走!
然后费用的初值就需要把这些扣掉的inf加回来。
end.
贴代码:
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 500
#define M 201000
#define inf 2000000
using namespace std;
struct KSD
{
int u,v,w,len,next;
}e[M<<3];/*瞎开的大小*/
int head[N],cnt;/*网络流图*/
void add(int u,int v,int w,int len)
{
++cnt;
e[cnt].u=u,e[cnt].v=v,e[cnt].w=w;
e[cnt].len=len,e[cnt].w=w;
e[cnt].next=head[u],head[u]=cnt;
}
int map[N][N];/*预处理的floyd图*/
int n,m,p;
int S,s,T;
long long dist[N],fee;
int pre[N];
bool in[N];
long long spfa()
{
memset(dist,0x3f,sizeof(dist));
queue<int>q;
int i,u,v;
dist[S]=0;
in[S]=1;
q.push(S);
while(!q.empty())
{
u=q.front();q.pop();in[u]=0;
for(i=head[u];i;i=e[i].next)
{
v=e[i].v;
if(!e[i].len)continue;
if(dist[v]>dist[u]+e[i].w)
{
dist[v]=dist[u]+e[i].w;
pre[v]=i;
if(!in[v])
{
in[v]=1;
q.push(v);
}
}
}
}
return dist[T];
}
void handle()
{
for(int i=pre[T];i;i=pre[e[i].u])
{
e[i].len-=1;
e[i^1].len+=1;
}
}
void build()
{
int i,j;
cnt=1;
s=0,S=2*n+1,T=2*n+2;
add(S,s,0,p);
add(s,S,0,0);
add(s,T,0,p);
add(T,s,0,0);
for(i=1;i<=n;i++)
{
add(s,i*2-1,map[s][i],1);
add(i*2-1,s,-map[s][i],0);
add(i*2-1,i*2,-inf,1);
add(i*2,i*2-1,inf,0);
add(i*2,T,0,1);
add(T,i*2,0,0);
}
for(i=1;i<=n;i++)
{
for(j=i+1;j<=n;j++)
{
add(i*2,j*2-1,map[i][j],1);
add(j*2-1,i*2,-map[i][j],0);
}
}
}
int main()
{
freopen("B.in","r",stdin);
freopen("B.out","w",stdout);
int i,j,k;
int a,b,c;
scanf("%d%d%d",&n,&m,&p);
memset(map,0x3f,sizeof(map));
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&c);
map[a][b]=map[b][a]=min(map[a][b],c);
}
for(i=0;i<=n;i++)map[i][i]=0;
for(k=0;k<=n;k++)for(i=0;i<=n;i++)for(j=0;j<=n;j++)if(k<=i||k<=j)map[i][j]=min(map[i][j],map[i][k]+map[k][j]);//floyd
build();
fee=inf*n;
long long temp;
while(temp=spfa(),temp<0x3f3f3f3f3f3f3f3fll)
{
fee+=temp;
handle();
}
cout<<fee<<endl;
fclose(stdin);
fclose(stdout);
return 0;
}