Quantcast
Channel: CSDN博客推荐文章
Viewing all articles
Browse latest Browse all 35570

HDU 3251 最小割

$
0
0

题意:国王赏赐给你一些城市,但是他不希望可以从首都(编号1)到达任何你的城市。

有m条边连通各个城市,每条边有一个值,为毁掉这条边需要的花费,你的每个城市有一个收入。

问,最后毁掉哪些边,可以使你的收入最高。

思路:将每条边的价值看成流量,连接两个城市,每个你的城市的收入看成流量,与汇点相连。源点为首都(编号1) ,求1-T的最小割。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2005
#define inf 1<<28
#define LL(x) (x<<1)
#define RR(x) (x<<1|1)
#define REP(i,s,t) for(int i=(s);i<=(t);++i)
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define PII pair<int,int>
using namespace std;
inline void readint(int &ret)
{
    char c;
    do
    {
        c = getchar();
    }
    while(c < '0' || c > '9');
    ret = c - '0';
    while((c=getchar()) >= '0' && c <= '9')
        ret = ret * 10 + ( c - '0' );
}

struct kdq
{
    int s ,e ,l ,next ;
} ed[Max * 100] ;
int head[Max] ,num ;
void add(int s ,int e ,int l )
{
    ed[num].s = s ;
    ed[num].e = e ;
    ed[num].l = l ;
    ed[num].next = head[s] ;
    head[s] = num ++ ;

    ed[num].s = e ;
    ed[num].e = s ;
    ed[num].l = 0 ;
    ed[num].next = head[e] ;
    head[e] = num ++ ;
}

int deep[Max] ;
int S, T ;
int qe[Max * 100] ;
int dinic_bfs()
{
    mem(deep,-1) ;
    deep[S] = 0 ;
    int h = 0 , t = 0 ;
    qe[h ++ ] = S ;
    while( h > t )
    {
        int tt = qe[t ++ ] ;
        for (int i = head[tt] ; ~i ; i = ed[i].next )
        {
            int e = ed[i].e ;
            int l = ed[i].l ;
            if(l > 0 && deep[e] == -1)
            {
                deep[e] = deep[tt] + 1 ;
                qe[h ++ ] = e ;
            }
        }
    }
    return deep[T] != -1 ;
}
int dinic_dfs(int now ,int f)
{
    if(now == T)return f ;
    int flow = 0 ;
    for (int i = head[now] ; ~ i ; i = ed[i].next )
    {
        int e = ed[i].e ;
        int l = ed[i].l ;
        if(l > 0 && (f - flow ) >0 && deep[e] == deep[now] + 1)
        {
            int mm = min(l ,f - flow) ;
            int nn = dinic_dfs(e,mm) ;
            flow += nn ;
            ed[i].l -= nn ;
            ed[i ^ 1].l += nn ;
        }
    }
    if(!flow) deep[now] = -2 ;
    return flow ;
}
int dinic()
{
    int flow = 0 ;
    while(dinic_bfs())
    {
        flow += dinic_dfs(S,inf) ;
    }
    return flow ;
}

bool vis[Max] ;
void dfs(int now)//找与首都相连的城市
{
    vis[now] = 1 ;
    for (int i = head[now] ; ~i ; i = ed[i].next )
    {
        int e = ed[i].e ;
        int l = ed[i].l ;
        if(l > 0 && !vis[e])
            dfs(e) ;
    }
}

PII edge[Max * 100] ;
int Q[Max] ,Qn ;
void init()
{
    mem(head,-1) ;
    num = 0 ;
    mem(vis,0) ;
    Qn = 0 ;
}
int main()
{
    int  t ;
    readint(t) ;
    int cas = 0 ;
    while( t -- )
    {
        init() ;
        int n , m , f ;
        readint(n) ;
        readint(m) ;
        readint(f) ;
        S = 1 ;
        T = n + 1 ;
        REP(i,0,m - 1)
        {
            int a , b , c ;
            readint(a) ;
            readint(b) ;
            readint(c) ;
            add(a,b,c) ;
            edge[i].first = a ;
            edge[i].second = b ;
        }
        int sum = 0 ;
        while( f -- )
        {
            int v ,w ;
            readint(v) ;
            readint(w) ;
            add(v, T ,w) ;
            sum += w ;
        }
        printf("Case %d: %d\n", ++ cas,sum - dinic()) ;
        dfs(1) ;
        REP(i,0, m - 1)
        if(vis[edge[i].first] && !vis[edge[i].second])Q[Qn ++ ] = i + 1 ;
        printf("%d",Qn) ;
        REP(i,0,Qn - 1)printf(" %d",Q[i]) ;
        puts("") ;
    }
    return 0;
}


作者:kdqzzxxcc 发表于2013-5-9 22:54:27 原文链接
阅读:52 评论:0 查看评论

Viewing all articles
Browse latest Browse all 35570

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>