zoukankan      html  css  js  c++  java
  • [HDU 3521] [最小割] Being a Hero

    题意:

    在一个有向图中,有n个点,m条边$n le 1000 And And  m le 100000$

    每条边有一个破坏的花费,有些点可以被选择并获得对应的金币。

    假设一个可以选的点是$x$,你只有破坏了从1号点到$x$的路,才可以得到$x$对应的金币。

    思路:

    点和边的区别在于,你放弃一个点得到0,选择一个点得到val。你放弃选择一条边得到0,选择一条边得到 - val。

    那么我们先把每个点的权值加到ans中,最够减去这个图的最小割即可。

    由于要输出破坏边的方案,所以要dfs染色,又由于是有向边,所以破坏的边是起点属于s的边。

    // #pragma GCC optimize(2)
    // #pragma GCC optimize(3)
    // #pragma GCC optimize(4)
    #include <algorithm>
    #include  <iterator>
    #include  <iostream>
    #include   <cstring>
    #include   <cstdlib>
    #include   <iomanip>
    #include    <bitset>
    #include    <cctype>
    #include    <cstdio>
    #include    <string>
    #include    <vector>
    #include     <stack>
    #include     <cmath>
    #include     <queue>
    #include      <list>
    #include       <map>
    #include       <set>
    #include   <cassert>
    //#include <unordered_set>
    //#include <unordered_map>
    // #include<bits/extc++.h>
    // using namespace __gnu_pbds;
    using namespace std;
    #define pb push_back
    #define fi first
    #define se second
    #define debug(x) cerr<<#x << " := " << x << endl;
    #define bug cerr<<"-----------------------"<<endl;
    #define FOR(a, b, c) for(int a = b; a <= c; ++ a)
    
    typedef long long ll;
    typedef long double ld;
    typedef pair<int, int> pii;
    typedef pair<ll, ll> pll;
    
    const int inf = 0x3f3f3f3f;
    const ll inff = 0x3f3f3f3f3f3f3f3f;
    const int mod = 1e9+7;
    
    
    template<typename T>
    inline T read(T&x){
        x=0;int f=0;char ch=getchar();
        while (ch<'0'||ch>'9') f|=(ch=='-'),ch=getchar();
        while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
        return x=f?-x:x;
    }
    
    /**********showtime************/
                const int maxn = 1009;
                int head[maxn], gtot = 0;
                struct Edge{
                    int u, v, w;
                    int id;
                    int nxt;
                } edge[300009];
                void addedge(int u, int v, int w, int id) {
                    edge[gtot].u = u;
                    edge[gtot].v = v;
                    edge[gtot].w = w;
                    edge[gtot].nxt = head[u];
                    edge[gtot].id = id;
                    head[u] = gtot++;
    
                    edge[gtot].u = v;
                    edge[gtot].v = u;
                    edge[gtot].w = 0;
                    edge[gtot].nxt = head[v];
                    edge[gtot].id = 0;
                    head[v] = gtot++;
                }
                int n,m,f;
                vector<int>vec;
                int cur[maxn],dis[maxn];
                bool bfs(int s, int t) {
                    for(int i=s; i<=t; i++) {
                        cur[i] = head[i];
                        dis[i] = inf;
                    }
                    dis[s] = 0; queue<int>que;
                    que.push(s);
                    while(!que.empty()) {
                        int u = que.front(); que.pop();
                        for(int i=head[u]; ~i; i=edge[i].nxt) {
                            int v = edge[i].v, w = edge[i].w;
                            if(w > 0 && dis[v] > dis[u] + 1) {
                                dis[v] = dis[u] + 1;
                                que.push(v);
                            }
                        }
                    }
                    return dis[t] < inf;
                }
                int dfs(int u, int t, int maxflow) {
                    if(u == t || maxflow == 0) return maxflow;
                    for(int i=cur[u]; ~i; i=edge[i].nxt) {
                        cur[u] = i;
                        int v = edge[i].v, w = edge[i].w;
                        if(w > 0 && dis[v] == dis[u] + 1) {
                            int f = dfs(v, t, min(maxflow, w));
                            if(f > 0) {
                                edge[i].w -= f;
                                edge[i ^ 1].w += f;
                                return f;
                            }
                        }
                    }
                    return 0;
                }
                int dinic(int s,  int t) {
                    int flow = 0;
                    while(bfs(s, t)) {
                        while(int f = dfs(s, t, inf))
                            flow += f;
                    }
                    return flow;
                }
                int col[maxn];
                void colnode(int u) {
                    col[u] = 1;
                    for(int i=head[u]; ~i; i= edge[i].nxt) {
                        int v = edge[i].v, w = edge[i].w;
                        if(w && col[v] == 0) colnode(v);
                    }
                }
    int main(){
                int T;  scanf("%d", &T);
                int cas = 0;
                while(T--) {
                    scanf("%d%d%d", &n, &m, &f);
                    int s = 0, t = n + 1;
                    for(int i=s; i<=t; i++) head[i] = -1, col[i] = 0;
                    gtot = 0;
    
                    for(int i=1; i<=m; i++) {
                        int u, v, w;
                        scanf("%d%d%d", &u, &v, &w);
                        addedge(u, v, w, i);
                    }
    
                    int sum = 0;
                    addedge(s, 1, inf, 0);
                    for(int i=1; i<=f; i++) {
                        int u, w;
                        scanf("%d%d", &u, &w);
                        addedge(u, t, w, 0);
                        sum += w;
                    }
    
                    sum = sum - dinic(s, t);
                    printf("Case %d: %d
    ", ++cas, sum);
                    colnode(s);
                    vec.clear();
                    for(int i=0; i<gtot; i++) {
                        int u = edge[i].u, v = edge[i].v, w = edge[i].w;
                        int id = edge[i].id;
                        if(col[u] == 1 && col[v] == 0 && id) {
                            vec.pb(id);
                        }
                    }
                    printf("%d", vec.size());
    //                sort(vec.begin(), vec.end());
                    for(int v : vec) {
                        printf(" %d", v);
                    }
                    puts("");
                }
                return 0;
    }
    View Code
  • 相关阅读:
    创建索引资源正忙的解决方案及原理
    MYSQL统计多个count_mysql 不同条件count ,多条件count()
    spark foreachPartition算子
    nginx部署安装
    Sqoop 并行度调整 m 以及 splitby
    sqoop报错
    idea 下1载
    Linux下nginx的安装
    电脑清除C盘文件夹
    深入理解计算机原理(csapp第三版)——datalab
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/11666555.html
Copyright © 2011-2022 走看看