zoukankan      html  css  js  c++  java
  • poj2987 Firing

      以前只是A过很简单的最大闭合权像hdu1565之类,完全的最大流模板题。但是都完全不太懂最大闭合权的定义及其用途。

     关于最大流的基础知识,大家可以自己网上搜索关键字。有点基础的哥们妹们,推荐看看胡伯涛最小割模型在信息学竞赛中的应用》,里面除了很多理论知识以外还有很多不错题集,大家可以练练。

     最大闭合权,是最大流一个很经典的应用,关键字:闭合图最大闭合权。

     这种题目表现的模型通常是A-->B-->C,即A事件发生,其后续事件也一定要发生。

     如果每个事件发生都有一个效益值的,用最大流算法便可以求出这种效益的最值。

     这个题目的另外一个问题是要求删掉的最少点数,乍一看好像很陌生,但是,大家不妨自己举个例子就可以发现这个就是传说中——最简的 、最小割集!

     最小割集固然是可能有很多个的,分割的位置便是网络中满流的位置。

     这道题求最简的最小割,那就是从源点开始,遍历所有可行边所访问的点集!

     帖个水水的代码,希望没有寒碜到大家。WA了n多次,后来发现是计算最大流函数的返回值忘了改成lli。我的钛合金**眼啊!!!!

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 using namespace std;
      5 typedef long long lli;
      6 const int maxn = 5010;
      7 const int maxe = 400100;
      8 const lli maxf = 1LL<<50;
      9 #define smaller(a,b) ((a)<(b)?(a):(b))
     10 struct edge{
     11        int u,v;
     12        lli c;
     13        edge(int a=0,int b=0,lli d=0){ u=a, v=b, c=d; }
     14 }e[maxe];
     15 int head[maxn];
     16 int next[maxe];
     17 int cnt;
     18 void add(int u,int v,lli c){
     19      e[cnt] = edge(u,v,c);
     20      next[cnt] = head[u], head[u] = cnt++;
     21      //printf("cnt = %d,	%d --> %d with c = %d, next = %d
    ",cnt-1,u,v,c,next[cnt-1]);
     22      e[cnt] = edge(v,u,0);
     23      next[cnt] = head[v], head[v] = cnt++;
     24 }
     25 //*****//
     26 int source,sink,maxdep;
     27 int dep[maxn],gap[maxn];
     28 int cur[maxn],trace[maxn],que[maxn],top;
     29 void setGD(){
     30      for(int i=0;i<=maxdep;i++) dep[i] = maxdep;
     31      dep[sink] = 0;
     32      memset(gap,0,sizeof(gap));
     33      gap[dep[sink]] = 1;
     34      gap[maxdep] = maxdep;
     35      int front,rear,u,v;
     36      front = rear = 0;
     37      que[rear++] = sink;
     38      while(front != rear){
     39            u = que[front++];
     40            if(front >= maxn) front = 0;
     41            for(int i=head[u];i!=-1;i=next[i]){
     42                  v = e[i].v;
     43                  if(e[i].c>0 || dep[v] <= dep[u]+1) continue;
     44                  dep[v] = dep[u]+1;
     45                  gap[dep[v]]++;
     46                  que[rear++] = v;
     47                  if(rear >= maxn) rear = 0;
     48            }
     49      }
     50 }
     51 lli maxF(){
     52     setGD();
     53     for(int i=0;i<=maxdep;i++) cur[i] = head[i];
     54     int u=source,i;
     55     top = 0;
     56     lli flow = 0;
     57     while(dep[source] <= maxdep){
     58         if(u == sink){
     59              lli tf = maxf;
     60              int ins;
     61              for(i=0;i<top;i++){ //找瓶颈边
     62                 if(tf > e[trace[i]].c){
     63                       tf = e[trace[i]].c;
     64                       ins = i;
     65                 }
     66              }
     67              /*
     68              for(i=0;i<top;i++)
     69                 printf("%d -> ",e[trace[i]].u);
     70              printf("%d , temp_flow = %d
    ",e[trace[top-1]].v,tf);
     71              */
     72              for(i=0;i<top;i++){
     73                 e[trace[i]].c -= tf;
     74                 e[trace[i]^1].c += tf;
     75              }
     76              flow += tf;
     77              u = e[trace[ins]].u, top = ins;
     78         }
     79         if(u != sink && gap[dep[u]-1]==0) break;
     80         for(i=cur[u];i!=-1;i=next[i])
     81              if(e[i].c > 0 && dep[u] == dep[e[i].v] + 1)
     82                        break;
     83         if(i != -1) {
     84              trace[top++] = i;
     85              cur[u] = i;
     86              u = e[i].v;
     87         }
     88         else {
     89              int mindep = maxdep;
     90              for(i=head[u];i!=-1;i=next[i]){
     91                  if(e[i].c > 0 && dep[e[i].v] < mindep)
     92                            mindep = dep[e[i].v], cur[u] = i;
     93              }
     94              gap[dep[u]]--;
     95              dep[u] =  mindep + 1;
     96              gap[dep[u]]++;
     97              if(u != source)
     98                 u = e[trace[--top]].u;
     99         }
    100     }
    101     return flow;
    102 }
    103 //**********************//
    104 int visited[maxn];
    105 int value[maxn];
    106 void initial()
    107 {
    108      cnt = 0;
    109      memset(head,-1,sizeof(head));
    110      memset(visited,0,sizeof(visited));
    111      //initial source ,sink and maxdep;
    112 }
    113 int era;
    114 void search(int u){
    115     //cout<<"u = "<<u<<endl;
    116     visited[u] = 1;
    117     era++;
    118     for(int i=head[u];i>=0;i=next[i])
    119     if(!visited[e[i].v] && e[i].c)
    120         search(e[i].v);
    121 }
    122 int main()
    123 {
    124     int n,m;
    125     while(scanf("%d%d",&n,&m) != EOF){
    126         lli sum = 0;
    127         int u,v,c;
    128         initial();
    129         source=0,sink=n+2,maxdep=sink+2;
    130         for(int i=1;i<=n;i++){
    131             scanf("%d",&c);
    132             value[i] = c;
    133             if(c > 0) add(source,i,c), sum+=c;
    134             else if(c < 0) add(i,sink,-c);
    135         }
    136         for(int i=0;i<m;i++)
    137             scanf("%d%d",&u,&v), add(u,v,maxf);
    138         lli ret = maxF();
    139         //if(ret >= sum) puts("0 0");  else {
    140             era = 0;
    141             search(source);
    142             cout<<(era-1)<<" "<<(sum-ret)<<endl;
    143         //}
    144     }
    145     return 0;
    146 }
    View Code
  • 相关阅读:
    P5283 [十二省联考2019]异或粽子 可持久化字典树
    P3293 [SCOI2016]美味 最大异或值 主席树
    P4735 最大异或和 可持久化trie树
    P4551 最长异或路径 trie树
    html/css静态网页制作
    在一个div里,列表样式图片进行float,实现水平排序
    css的网页布局用position
    您右下角有份、、、
    登录注册页面和页面跳转
    相对路径 绝对路径
  • 原文地址:https://www.cnblogs.com/karlvin/p/3223826.html
Copyright © 2011-2022 走看看