热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

hust1342(有上下界的最小流)

CheatSecretlyTimeLimit:1SecMemoryLimit:128MBSubmissions:269Sol

Cheat Secretly

Time Limit: 1 Sec   Memory Limit: 128 MB
Submissions: 269   Solved: 77

Description

HH Big Cow(HBC) has taken part in an interesting treasure finding match.
In the match there are N transmitting nodes(labeled from 1 to N), and between these nodes there are M directional roads. In the middle of some roads there may be a “gift-spot”, where a beautiful girl gives a gift to the contestant who passes that road. The one who gets most gifts wins!
Winning the match is so easy for HBC, so he is thinking of a more challenging thing —— collecting gifts from ALL the girls. HBC has an amazing ability to achieve this goal: When he comes to a dead end, he can transfer himself to another node arbitrarily.
With that ability, of course he can achieve the goal of meeting all the girls, however, cheating is not good! So he decides to use the ability as few as possible. Now he wants to know the fewest times he should use that ability to achieve his goal.

NOTE: 
1. The graph in the match is a directed acyclic graph (DAG).
2. There is at most one road between any two nodes.

Input

The input contains multiple case.
Line 1 an integer T : number of test cases.
Line 2 two integer N, M:
N for number of nodes. (2 <= N <= 500)
M for number of roads. (1 <= M <= 10000)
Lines 3..M+2 each line three integers a, b, c: representing a directed roads from a to b. (1 <= a, b <= N)
c = 1, then there is a gift spot on this road.
c = 0, then there is no gift spot on this road.

Output

For each case output one line representing the fewest number of ability HBC should use.

Sample Input

2

4 2

1 2 1
3 4 1

6 7

1 2 1
2 3 1
3 4 1
1 4 0
5 2 1
3 6 1
5 6 0

Sample Output

Case #1: 2
Case #2: 2

HINT

Source

Yang Xiaobin, HUST Campus 2009

自从离开湖大,荒废许久,话说这题还是离开那天敲完代码wa了,一直到今天才A掉,首先构图就是个错误,然后各种Debug。。。

题目链接:http://acm.hust.edu.cn/thx/problem.php?id=1342

分析:这题很明显的有上下界的最小流,构图比较简单,先把读入的边连上,然后增加一个源点一个汇点,源点连上所有点,所有点连上汇点,有礼物的边ij在in[i]中减1,在in[j]中加一,最后再增设一源一汇,枚举所有点in为正的连上源,in为负的连上汇,做求一次最大流,再连上原来的汇和源,再求最大流,此时原来的源到汇即答案

代码:

#include
using namespace std;
const int mm=111111;
const int mn=1111;
const int oo=1000000000;
int node,src,dest,edge,n,m;
int ver[mm],flow[mm],next[mm];
int head[mn],work[mn],dis[mn],q[mn],in[mn];
inline int min(int a,int b)
{
    return a=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;
}
void Dinic_flow()
{
    while(Dinic_bfs())
    {
        for(int i=0; i0)addedge(src,i,in[i]);
        if(in[i]<0)addedge(i,dest,-in[i]);
    }
    Dinic_flow();
    addedge(dest0,src0,oo);
    Dinic_flow();
    for(i=head[dest0]; i>=0; i=next[i])
        if(ver[i]==src0)return flow[i^1];
}
int main()
{
    int i,u,v,k,c,t,cas=0;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        prepare(n+2,0,n+1);
        for(i=1; i<=n; ++i)
            addedge(src,i,oo),addedge(i,dest,oo),in[i]=0;
        for(i=1; i<=m; ++i)
        {
            scanf("%d%d%d",&u,&v,&c);
            if(c)--in[u],++in[v];
            addedge(u,v,oo);
        }
        printf("Case #%d: %d\n",++cas,limit_min_flow());
    }
    return 0;
}



推荐阅读
author-avatar
余挺空荡荡_833
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有