计蒜客-不合格米线

题目不会做!,转发大牛的

某天江南米线公司发生了一件倒霉的事情:公司不小心把不合格米线发出去给零售商了。很不幸,你发现这件事的时候,这部分米线已经在运算路上。这个零售物流网络很大,而且关系复杂。你知道这米线要发给哪个零售商,但是要把这批米线送到他手中有许多种途径。物流网由一些仓库和运输卡车组成,每辆卡车都在各自固定的两个仓库之间单向运输米线。在追查这些有不合格米线的时候,必须保证它不被送到零售商手里,所以必须使某些运输卡车停止运输,但是停止每辆卡车都会有一定的经济损失。你的任务是,在保证不合格米线不送到零售商的前提下,制定出停止卡车运输的方案,使损失最小。

输入第一行包括空格分隔开的两个整数NM2≤N320M1000。其中,N表示仓库的数目,M表示运输卡车的数量。“仓库1代表发货工厂,仓库N代表有不合格米线将要发往的零售商。

输入第2行到第M+1行:每行包括空格分隔的3个整数SiEiCi。其中SiEi表示这辆卡车的出发仓库,目的仓库。Ci(0 <= C<= 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\n",cnt);
    sort(Id+1,Id+1+cnt);
    for (int i=1;i<=cnt;i++)    printf("%d\n",Id[i]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/kuroko_ghh/article/details/80157302
今日推荐