给出n个点,m条边,每条边有个长度,且只能走一次,让你规划一种方案,使得1到n的路径条数最多而且总路程最短。
很明显这是一道网络流的题目,我们只要把每一条边的长度改成费用,流量为1,即可。
没有用zkw网络流写法。
#include
#include
#include
#include
#include
using namespace std;
struct edge{
int x,y,next,c,cos;
}s[40410];
int n,m;
int len=1;
int begin,end;
int d[410],mmin[410],last[410],first[410];
bool tf[410];
queue f;
void ins(int x,int y,int c,int cos){
len++;
s[len]=(edge){x,y,first[x],c,cos};first[x]=len;
}
bool SPFA(int &cost,int&flow){
memset(d,63,sizeof(d));
memset(tf,false,sizeof(tf));
memset(mmin,63,sizeof(mmin));
memset(last,0,sizeof(last));
f.push(begin);d[begin]=0;tf[begin]=true;
while(!f.empty()){
int x=f.front();f.pop();tf[x]=false;
for(int i=first[x];i!=0;i=s[i].next){
int y=s[i].y;
if(d[y]>d[x]+s[i].cos && s[i].c>0){
mmin[y]=min(mmin[x],s[i].c);
d[y]=d[x]+s[i].cos;
last[y]=i;
if(!tf[y]){
tf[y]=true;
f.push(y);
}
}
}
}
if(d[end]==d[end+1]) return false;
cost+=d[end]*mmin[end];
flow+=mmin[end];
int now=end;
while(now!=begin){
s[last[now]].c-=mmin[end];
s[last[now]^1].c+=mmin[end];
now=s[last[now]].x;
}
return true;
}
void MCMF(){
int cost=0,flow=0;
while(SPFA(cost,flow));
printf("%d %d\n",flow,cost);
}
int main(){
scanf("%d %d",&n,&m);
begin=0,end=2*n+1;
int x,y,c;
for(int i=1;i<=m;i++){
scanf("%d %d %d",&x,&y,&c);
ins(x,y+n,1,c);
ins(y+n,x,0,-c);
}
for(int i=1;i<=n;i++){
ins(i+n,i,1,0);
ins(i,i+n,0,0);
}
ins(begin,1,1e9,0);ins(n+n,end,1e9,0);
MCMF();
}