usaco 4.4 Pollutant Control(最小割最少边数字典序最小)

Pollutant Control
Hal Burch

It's your first day in Quality Control at Merry Milk Makers, and already there's been a catastrophe: a shipment of bad milk has been sent out. Unfortunately, you didn't discover this until the milk was already into your delivery system on its way to stores. You know which grocer that milk was destined for, but there may be multiple ways for the milk to get to that store.

The delivery system is made up of a several warehouses, with trucks running from warehouse to warehouse moving milk. While the milk will be found quickly, it is important that it does not make it to the grocer, so you must shut down enough trucks to ensure that it is impossible for the milk to get to the grocer in question. Every route costs a certain amount to shut down. Find the minimum amount that must be spent to ensure the milk does not reach its destination, along with a set of trucks to shut down that achieves this goal at that cost.

PROGRAM NAME: milk6

INPUT FORMAT

Line 1:Two space separated integers, N and M. N (2 <= N <= 32) is the number of warehouses that Merry Milk Makers has, and M (0 <= M <= 1000) is the number of trucks routes run. Warehouse 1 is actually the productional facility, while warehouse N is the grocer to which which the bad milk was destined.
Line 2..M+1:Truck routes: three space-separated integers, Si, Ei, and Ci. Si and Ei (1 <= Si,Ei <= N) correspond to the pickup warehouse and dropoff warehouse for the truck route. Ci (0 <= Ci <= 2,000,000) is the cost of shutting down the truck route.

SAMPLE INPUT (file milk6.in)

4 5
1 3 100
3 2 50
2 4 60
1 2 40
2 3 80

OUTPUT FORMAT

The first line of the output should be two integers, C and T. C is the minimum amount which must be spent in order to ensure the our milk never reaches its destination. T is the minimum number of truck routes that you plan to shut down in order to achive this goal. The next T lines sould contain a sorted list of the indexes of the truck routes that you suggest shutting down. If there are multiple sets of truck routes that achieve the goal at minimum cost, choose one that shuts down the minimum number of routes. If there are still multiple sets, choose the one whose initial routes have the smallest index.

SAMPLE OUTPUT (file milk6.out)

60 1
3

题意:给你一张有向图,然后每条边有一个权值,表示去掉这条边的费用,至少要花费多少钱,才能使得1不能到达n,满足费用最低的情况下使边数最少,边数最少的情况下使字典序最小。。。

分析:这题说实话,我只想出最小花费就是最小割,也就是求最大流,其他两个问,完全没头绪。。。找了n篇题解,都讲得不是很明白,懂了一个修改边容量的方法来求第二问,第三问解法很多,不过貌似都是错的= =,具体这篇讲得很明白了

这题确实是个好题,不得不好好学一下啊,看来我图论还是很弱很弱。。。

代码:

/*
ID: 15114582
PROG: milk6
LANG: C++
*/

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mm=2222;
const int mn=55;
const int oo=2e9;
int src,dest,node,edge;
int ver[mm],flow[mm],Next[mm];
int head[mn],work[mn],dis[mn],q[mn],vis[mm];
void prepare(int _node,int _src,int _dest)
{
    node=_node,src=_src,dest=_dest;
    for(int i=0;i<node;++i)head[i]=-1;
    edge=0;
}
void addedge(int u,int v,int c)
{
    ver[edge]=v,flow[edge]=c,Next[edge]=head[u],head[u]=edge++;
    ver[edge]=u,flow[edge]=0,Next[edge]=head[v],head[v]=edge++;
}
bool Dinic_bfs()
{
    int i,u,v,l,r=0;
    for(i=0;i<node;++i)dis[i]=-1;
    dis[q[r++]=src]=0;
    for(l=0;l<r;++l)
        for(i=head[u=q[l]];i>=0;i=Next[i])
            if(flow[i]&&dis[v=ver[i]]<0)
            {
                dis[q[r++]=v]=dis[u]+1;
                if(v==dest)return 1;
            }
    return 0;
}
int Dinic_dfs(int u,int exp)
{
    if(u==dest)return exp;
    for(int &i=work[u],v,tmp;i>=0;i=Next[i])
        if(flow[i]&&dis[v=ver[i]]==dis[u]+1&&(tmp=Dinic_dfs(v,min(exp,flow[i])))>0)
        {
            flow[i]-=tmp;
            flow[i^1]+=tmp;
            return tmp;
        }
    return 0;
}
long long Dinic_flow()
{
    int i,delta;
    long long ret=0;
    while(Dinic_bfs())
    {
        for(i=0;i<node;++i)work[i]=head[i];
        while(delta=Dinic_dfs(src,oo))ret+=delta;
    }
    return ret;
}
void recover()
{
    for(int i=0;i<edge;i+=2)
        flow[i]+=flow[i^1],flow[i^1]=0;
}
int main()
{
    freopen("milk6.in","r",stdin);
    freopen("milk6.out","w",stdout);
    int i,j,k,n,m,e;
    long long ans,tmp;
    while(~scanf("%d%d",&n,&m))
    {
        prepare(n+1,1,n);
        e=m+1;
        while(m--)
        {
            scanf("%d%d%d",&i,&j,&k);
            addedge(i,j,k*e+1);
        }
        ans=Dinic_flow();
        printf("%lld %lld\n",ans/e,ans%e);
        for(i=0;i<edge;i+=2)vis[i]=flow[i];
        for(i=0;i<edge;i+=2)
            if(!vis[i])
            {
                k=flow[i]+flow[i^1];
                flow[i]=flow[i^1]=0;
                recover();
                tmp=Dinic_flow();
                if(ans==tmp+k)ans=tmp,printf("%d\n",i/2+1);
                else flow[i]=k;
            }
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值