题目不会做!,转发大牛的
某天江南米线公司发生了一件倒霉的事情:公司不小心把不合格米线发出去给零售商了。很不幸,你发现这件事的时候,这部分米线已经在运算路上。这个零售物流网络很大,而且关系复杂。你知道这米线要发给哪个零售商,但是要把这批米线送到他手中有许多种途径。物流网由一些仓库和运输卡车组成,每辆卡车都在各自固定的两个仓库之间单向运输米线。在追查这些有不合格米线的时候,必须保证它不被送到零售商手里,所以必须使某些运输卡车停止运输,但是停止每辆卡车都会有一定的经济损失。你的任务是,在保证不合格米线不送到零售商的前提下,制定出停止卡车运输的方案,使损失最小。
输入第一行包括空格分隔开的两个整数N、M(2≤N≤32;0≤M≤1000)。其中,N表示仓库的数目,M表示运输卡车的数量。“仓库1”代表发货工厂,仓库N代表有不合格米线将要发往的零售商。
输入第2行到第M+1行:每行包括空格分隔的3个整数Si、Ei、Ci。其中Si,Ei表示这辆卡车的出发仓库,目的仓库。Ci(0 <= Ci <= 2,000,000)表示让这辆卡车停止运输的损失。
输出第一行包括空格分隔的两个整数X和T,X表示最小的损失,T表示要停止的最少卡车数。接下来T行表示你要停止哪几条线路。如果有多种方案使损失最小,输出停止的线路最少的方案。如果仍然还有相同的方案,请选择开始输入顺序最小的。
样例输入
4 5 1 3 100 3 2 50 2 4 60 1 2 40 2 3 80
样例输出
60 1 3
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cctype>
#define oo 0x7fffffff
using namespace std;
int head,tail,level[110],q[110],s,t,sum=0,rev[10010],len=0,lin[110];
int m,n,Id[10010],cnt=0,ans;
struct node{
int y,v,ne;
}edge[10010];
struct node1{
int v,id;
}e[10010];
inline bool mycmp(node1 a,node1 b)
{return a.v>b.v||a.v==b.v&&a.id<b.id;}
inline bool mycmp1(int a,int b)
{return a<b;}
void addedge(int x,int y,int v){
edge[++len].y=y;edge[len].v=v;edge[len].ne=lin[x];lin[x]=len;rev[len]=len+1;
edge[++len].y=x;edge[len].v=0;edge[len].ne=lin[y];lin[y]=len;rev[len]=len-1;
}
int read(){
int x=0,y=1;char ch=getchar();
while (!isdigit(ch)){if (ch=='-')y=-1;ch=getchar();}
while (isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*y;
}
bool make_level(){
head=0,tail=1;q[1]=s;memset(level,-1,sizeof(level));level[s]=0;
while (head++<tail){
int tn=q[head];
for (int i=lin[tn],y;i;i=edge[i].ne)
if (edge[i].v&&level[y=edge[i].y]==-1){
level[y]=level[tn]+1;
q[++tail]=y;
}
}
return level[t]!=-1;
}
int max_flow(int k,int flow){
if (k==t) return flow;
int maxflow=0,d;
for (int i=lin[k];i&&maxflow<flow;i=edge[i].ne)
if (edge[i].v&&level[edge[i].y]==level[k]+1)
if (d=max_flow(edge[i].y,min(flow-maxflow,edge[i].v))){
edge[i].v-=d;edge[rev[i]].v+=d;maxflow+=d;
}
if (!maxflow)level[k]=-1;
return maxflow;
}
void dinic(){
int d;
while (make_level()) while (d=max_flow(s,oo)) sum+=d;
}
void init(){
n=read();m=read();
s=1,t=n;
int x,y,v;
for (int i=1;i<=m;i++){
x=read();y=read();v=read();
addedge(x,y,v);
}
}
int main(){
init();
dinic();
printf("%d ",sum);
ans=sum;
for (int j=1;j<=len;j+=2){edge[j].v+=edge[rev[j]].v;edge[rev[j]].v=0;}
for (int i=1;i<=m;i++){e[i].v=edge[i*2-1].v;e[i].id=i;}
sort(e+1,e+1+m,mycmp);
for (int i=1;i<=m&&ans;i++){
int id=e[i].id,v=e[i].v;
sum=0;
edge[id*2-1].v=0;
dinic();
for (int j=1;j<=len;j+=2){edge[j].v+=edge[rev[j]].v;edge[rev[j]].v=0;}
if (ans-sum==v){
ans=sum;
Id[++cnt]=id;
}
else edge[id*2-1].v=v;
}
printf("%d
",cnt);
sort(Id+1,Id+1+cnt);
for (int i=1;i<=cnt;i++) printf("%d
",Id[i]);
return 0;
}