zoukankan      html  css  js  c++  java
  • UVALive 7264 Kejin Game 网络流+最小割

    Kejin Game

    题意:一个人有一颗技能树, 现在它想修练到某个技能 (假设为x), 现在修一个技能有3种方式: 1, 将该技能的前置技能都学完了,才能学该技能。 2, 取消一个技能 与 另一个技能的前置关系, 也就是说修该技能的时候不需要先修取消了关系的前置技能。 3,无视前置关系, 直接修某个技能。 这3种方式都是需要花费一定的代价的,求修的S之后的最小代价。

    题解:网络流拆点, 把所有的点都复制一份, 每一个 i 都会对应一个 i' , 然后0为源点, 将(s,i) 相连, 流量上限为(修完前置技能后) 修该技能的花费。  将(i, i') 相连, 流量上限为直接修得该技能的花费。

    如果u 是 v的前置技能, 那么就将(u',v)建边, 花费为取消该技能的花费。 最后将 (x', t) 相连, 流量上限为 inf。 这样建完图之后, 我们就可以发现, 最小割就是修的 x 的最小花费。

    图片转载 Form here

    图上的1, 2, 3, 4  这4种割, 每种割法都可以修得目标技能, 那么最小割就是最后的解了。 最后 建完边之后跑出最大流 , 就是解了。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
     4 #define LL long long
     5 #define ULL unsigned LL
     6 #define fi first
     7 #define se second
     8 #define pb push_back
     9 #define lson l,m,rt<<1
    10 #define rson m+1,r,rt<<1|1
    11 #define max3(a,b,c) max(a,max(b,c))
    12 #define min3(a,b,c) min(a,min(b,c))
    13 typedef pair<int,int> pll;
    14 const int inf = 0x3f3f3f3f;
    15 const LL INF = 0x3f3f3f3f3f3f3f3f;
    16 const LL mod =  (int)1e9+7;
    17 const int N =1010;
    18 const int M = N*100;
    19 int n, m, s, t;
    20 int head[N], to[M], nx[M], w[M];
    21 int deep[N], cur[N];
    22 int tot;
    23 void add(int u, int v, int val){
    24     w[tot]  = val;
    25     to[tot] = v;
    26     nx[tot] = head[u];
    27     head[u] = tot++;
    28 }
    29 int bfs(int s, int t){
    30     queue<int> q;
    31     memset(deep, 0, sizeof deep);
    32     q.push(s);
    33     deep[s] = 1;
    34     while(!q.empty()){
    35         int u = q.front();
    36         q.pop();
    37         for(int i = head[u]; ~i; i = nx[i]){
    38             if(w[i] > 0 && deep[to[i]] == 0){
    39                 deep[to[i]] = deep[u] + 1;
    40                 q.push(to[i]);
    41             }
    42         }
    43     }
    44     if(deep[t] > 0) return 1;
    45     return 0;
    46 }
    47 int Dfs(int u, int t, int flow){
    48     if(u == t) return flow;
    49     for(int &i = cur[u]; ~i; i = nx[i]){
    50         if(deep[u]+1 == deep[to[i]] && w[i] > 0){
    51             int di = Dfs(to[i], t, min(w[i], flow));
    52             if(di > 0){
    53                 w[i] -= di, w[i^1] += di;
    54                 return di;
    55             }
    56         }
    57     }
    58     return 0;
    59 }
    60 int Dinic(int s, int t){
    61     int ans = 0, tmp;
    62     while(bfs(s, t)){
    63         for(int i = 0; i <= n*2+1; i++) cur[i] = head[i];
    64         while(tmp = Dfs(s, t, inf)) ans += tmp;
    65     }
    66     return ans;
    67 }
    68 void init(){
    69     memset(head, -1, sizeof(head));
    70     tot = 0;
    71 }
    72 int main(){
    73     scanf("%d", &t);
    74     while(t--){
    75         scanf("%d%d%d", &n, &m, &s);
    76         init();
    77         int a, b, c;
    78         for(int i = 1; i <= m; i++){
    79             scanf("%d%d%d", &a, &b, &c);
    80             add(a+n,b,c);
    81             add(b,a+n,0);
    82         }
    83         for(int i = 1; i <= n; i++){
    84             scanf("%d", &a);
    85             add(0,i,a);
    86             add(i,0,0);
    87         }
    88         for(int i = 1; i <= n; i++){
    89             scanf("%d", &a);
    90             add(i, i+n, a);
    91             add (i+n, i, 0);
    92         }
    93         add(s+n,2*n+1,inf);
    94         add(2*n+1,s+n,0);
    95         printf("%d
    ", Dinic(0,2*n+1));
    96     }
    97     return 0;
    98 }
    View Code

    第一次网络流拆点, 不是很明白为什么这样建边就好了, 想着各种将点与点各种关系连起来, 但是却没有办法实现求解。 需要加强建边的思维。

  • 相关阅读:
    程序多开原理记录
    BitTorrent协议规范(BitTorrent Protocol Specification)之Tracker HTTP/HTTPS Protocol第三部分
    到底什么是RBD?
    关于missing unit proxies.pas
    教你简单去除 Office 2007 盗版提示
    手把手教你使用WINDBG KO XXXX游戏驱动保护
    c# 模拟提交有附件表单(转)
    常用断点(OD中)
    delphi中Webbrowser
    PS3简易蓝光规格视频制作说明
  • 原文地址:https://www.cnblogs.com/MingSD/p/9340933.html
Copyright © 2011-2022 走看看