HDU 4411 Arrest

时间:2023-03-09 16:42:31
HDU 4411 Arrest

http://www.cnblogs.com/jianglangcaijin/archive/2012/09/24/2700509.html

思路:

S->0 流量为K费用0

0->i 流量为inf,费用为a[0][i]

0->T 流量为K,费用0

i->i+n 流量为1,费用为-inf

i+n->T 流量为1,费用为a[0][i]

 #include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define inf 1000000
int a[][],K;
int tot,go[],next[],first[],cost[],flow[];
int op[],dis[],c[],vis[],edge[],from[];
int S,T,n,m,ans;
int read(){
char ch=getchar();int t=,f=;
while (ch<''||ch>''){if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
void insert(int x,int y,int z,int l){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
flow[tot]=z;
cost[tot]=l;
}
void add(int x,int y,int z,int l){
insert(x,y,z,l);op[tot]=tot+;
insert(y,x,,-l);op[tot]=tot-;
}
bool spfa(){
for (int i=;i<=T;i++)
dis[i]=0x3f3f3f3f,vis[i]=;
int h=,t=;c[]=S;vis[S]=;dis[S]=;
while (h<=t){
int now=c[h++];
for (int i=first[now];i;i=next[i]){
int pur=go[i];
if (dis[pur]>dis[now]+cost[i]&&flow[i]){
dis[pur]=dis[now]+cost[i];
edge[pur]=i;
from[pur]=now;
if (vis[pur]) continue;
vis[pur]=;
c[++t]=pur;
}
}
vis[now]=;
}
return dis[T]!=0x3f3f3f3f;
}
void updata(){
int mn=0x3f3f3f3f;
for (int i=T;i!=S;i=from[i]){
mn=std::min(mn,flow[edge[i]]);
}
for (int i=T;i!=S;i=from[i]){
ans+=mn*cost[edge[i]];
flow[edge[i]]-=mn;
flow[op[edge[i]]]+=mn;
}
}
int main(){
while (scanf("%d",&n)!=EOF){
m=read();K=read();
if (n==&&K==&&m==) return ;
for (int i=;i<=T;i++) first[i]=;tot=;
S=*n+;T=S+;
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
if (i==j) a[i][j]=;
else a[i][j]=0x3f3f3f3f;
while(m--){
int u=read(),v=read(),w=read();
a[u][v]=std::min(a[u][v],w);
a[v][u]=std::min(a[v][u],w);
}
for (int k=;k<=n;k++)
for (int i=;i<=n;i++)
for (int j=;j<=n;j++)
a[i][j]=std::min(a[i][j],a[i][k]+a[k][j]);
add(S,,K,);
add(,T,K,);
for (int i=;i<=n;i++)
if (a[][i]<0x3f3f3f3f)
add(,i,inf,a[][i]);
for (int i=;i<=n;i++)
for (int j=i+;j<=n;j++)
if (a[i][j]<0x3f3f3f3f)
add(i+n,j,,a[i][j]);
for (int i=;i<=n;i++)
if (a[][i]<0x3f3f3f3f)
add(i+n,T,,a[][i]);
for (int i=;i<=n;i++)
add(i,i+n,,-inf);
ans=inf*n;
while (spfa()) updata();
printf("%d\n",ans);
}
}