• 计蒜客-不合格米线


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

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

    输入第一行包括空格分隔开的两个整数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
    ",cnt);
        sort(Id+1,Id+1+cnt);
        for (int i=1;i<=cnt;i++)    printf("%d
    ",Id[i]);
        return 0;
    }
    

  • 相关阅读:
    hdoj 1002 A + B Problem II
    hdoj 1234 开门人和关门人
    hdoj 2203 亲和串
    nyoj 73 比大小
    81B
    信息传递
    bzoj1787
    最少交换次数
    100803C
    火柴排队
  • 原文地址:https://www.cnblogs.com/kuroko-ghh/p/9363348.html
Copyright © 2020-2023  润新知