• hdu3251 最小割


    题意:

    给n个城市,m条有向边。每条边有权值,如今有些城市能够选择得到。可选的城市有一个价值。可是要满足从1到达不了这些城市,为了满足要求能够去掉一些边,须要花费边的权值,问终于得到的最大价值是多少,并给出方案。

    最小割 = 最大流

    建图非常easy。源点就是1,设置汇点T。

    按图中的有向边关系连边。

    对于全部的可选择的城市u,连一条u->T的容量为w的边。

    跑一遍最大流。即为最小割。

    ans = sum - 最小割。

    写出方案。就是走一遍bfs。看 哪些满流边(而且边的汇不是T,这是由于这种边是所选的城市扩展的边),打出来就好。


    代码:

    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<queue>
    #include<cmath>
    #include<cstring>
    using namespace std;
    const int N = 1000 + 10 ;
    const int inf = 1000000000;
    typedef long long ll;
    struct Edge
    {
        int from,to,cap,flow;
    };
    int n,m,s,t,num,f;
    int w[N],use[N];
    int vis[2*N],cur[2*N];
    vector<int> G[2*N];
    vector<Edge> edges;
    queue<int> cut;
    void init()
    {
        edges.clear();
        for(int i=1;i<=n;i++) G[i].clear();
        memset(vis,0,sizeof(vis));
    }
    int add(int u,int v,int c)
    {
        edges.push_back((Edge){u,v,c,0});
        edges.push_back((Edge){v,u,0,0});
        num = edges.size();
        G[u].push_back(num-2);
        G[v].push_back(num-1);
    }
    int bfs()
    {
        int front;
        memset(vis,0,sizeof(vis));
        vis[s] = 1;
        queue<int> q;
        q.push(s);
        while(!q.empty()){
            front = q.front(); q.pop();
            for(int i=0;i<G[front].size();i++)
            {
                Edge& e = edges[G[front][i]];
                if(!vis[e.to] && e.cap > e.flow)
                {
                    q.push(e.to);
                    vis[e.to] = vis[front]+1;
                }
            }
        }
        return vis[t];
    }
    int dfs(int x,int a)
    {
        if(x==t || a==0) return a;
        int f=0,flow=0;
        for(int i=0;i<G[x].size();i++){
            Edge& e = edges[G[x][i]];
            if(vis[e.to]==vis[x]+1 && (f=dfs(e.to,min(a,e.cap-e.flow)))>0 )
            {
                flow += f;
                e.flow += f;
                a -= f;
                edges[G[x][i]^1].flow -= f;
                if(a==0) break;
            }
        }
        return flow;
    }
    int dinic()
    {
        int flow = 0;
        while(bfs())
        {
            memset(cur,0,sizeof(cur));
            flow += dfs(s,inf);
        }
        return flow;
    }
    void find_cut()
    {
        while(!cut.empty()) cut.pop();
        memset(vis,0,sizeof(vis));
        vis[1] = 1;
        queue<int> q;
        q.push(1);
        int front;
        while(!q.empty()){
            front = q.front(); q.pop();
            for(int i=0;i<G[front].size();i++){
                Edge& e = edges[G[front][i]];
                if(!vis[e.to] && e.cap > e.flow){
                    vis[e.to] = 1;
                    q.push(e.to);
                }
            }
        }
        for(int i=1;i<=n;i++){
            if(vis[i])
                for(int j=0;j<G[i].size();j++){
                    Edge& e = edges[G[i][j]];
                    if(G[i][j]&1) continue;
                    if(e.to!=t  && !vis[e.to])
                        cut.push(G[i][j]/2+1);
                }
        }
        return ;
    }
    void print_cut()
    {
        int len = cut.size();
        int ro;
        cout<<len<<" ";
        for(int i=1;i<len;i++){
            ro = cut.front();
            cut.pop();
            printf("%d ",ro);
        }
        ro = cut.front();
        cut.pop();
        printf("%d
    ",ro);
    }
    int main()
    {
        int T,cas=0;
        scanf("%d",&T);
        while(T--){
            ll sum = 0;
            scanf("%d%d%d",&n,&m,&f);
            init();
            s = 1; t = n+1;
            for(int i=1;i<=m;i++){
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
            }
            for(int i=1;i<=f;i++){
                int u,w;
                scanf("%d%d",&u,&w);
                add(u,t,w);
                sum += w;
            }
            ll ans = dinic();
            find_cut();
            printf("Case %d: %lld
    ",++cas,sum-ans);
            print_cut();
        }
        return 0;
    }
    


  • 相关阅读:
    1121 Damn Single
    1122 Hamiltonian Cycle
    1123 Is It a Complete AVL Tree
    1420. Build Array Where You Can Find The Maximum Exactly K Comparisons
    1124 Raffle for Weibo Followers
    1125 Chain the Ropes
    测试面试题集-2.测试用例设计
    开奖|1024中奖名单公布以及Postman资料分享
    祝心想事成无Bug,1024快乐!
    1024福利|硬核无Bug,码上有红包!
  • 原文地址:https://www.cnblogs.com/claireyuancy/p/6790300.html
Copyright © 2020-2023  润新知