• poj3041


    最小覆盖=最大匹配,有时间看一下证明过程

      1 #include <iostream>
      2 #include <string>
      3 #include <vector>
      4 #include <cstdlib>
      5 #include <cmath>
      6 #include <map>
      7 #include <algorithm>
      8 #include <list>
      9 #include <ctime>
     10 #include <set>
     11 #include <queue>
     12 #include <cstring>
     13 #include <cstdio>
     14 using namespace std;
     15 #define INT_MAX 10000000
     16 #define N 1005
     17 #define CLR(arr, what) memset(arr, what, sizeof(arr))
     18 int capacity[N][N]; //容量
     19 int flow[N]; //残余流量
     20 int pre[N]; //前趋
     21 int n; //节点个数
     22 
     23 queue<int> Q;
     24 
     25 int BFS(int src, int des) {
     26     //初始化
     27     while (!Q.empty()) {
     28         Q.pop();
     29     }
     30     for (int i = 1; i < n + 1; i++) {
     31         pre[i] = -1;
     32     }
     33     pre[src] = 0;
     34     flow[src] = INT_MAX; //初始化源点的流量为无穷大
     35     Q.push(src);
     36     while (!Q.empty()) {
     37         int index = Q.front();
     38         Q.pop();
     39         if (index == des) { //找到了增广路径
     40             break;
     41         }
     42         for (int i = 1; i < n + 1; i++) {
     43             if (i != src && capacity[index][i] > 0 && pre[i] == -1) {
     44                 pre[i] = index;
     45                 //增广路残容流量
     46                 flow[i] = min(capacity[index][i], flow[index]);
     47                 Q.push(i);
     48             }
     49         }
     50     } //while
     51     if (pre[des] == -1) {
     52         return -1; //残留图中不存在增广路径
     53     } else {
     54         return flow[des];
     55     }
     56 }
     57 
     58 int MaxFlow(int src, int des) {
     59     int aug = 0;
     60     int sumflow = 0;
     61     while ((aug = BFS(src, des)) != -1) {
     62         int k = des; //利用前驱寻找路径
     63         while (k != src) {
     64             int last = pre[k];
     65             capacity[last][k] -= aug;
     66             capacity[k][last] += aug;
     67             k = last;
     68         }
     69         sumflow += aug;
     70     }
     71     return sumflow;
     72 }
     73 struct node {
     74     string in, out;
     75     int cap;
     76 };
     77 int checkin(string & a, string& b) {
     78     int sz = a.size();
     79     bool judge = 1;
     80     for (int i = 0; i < sz; i++) {
     81         if (a[i] == '2' || b[i] == '2') {
     82             continue;
     83         } else if (a[i] != b[i]) {
     84             judge = 0;
     85             break;
     86         }
     87     }
     88     if (1 == judge)
     89         return 1;
     90     return 0;
     91 }
     92 
     93 int cur[N]; //后继
     94 int dis[N]; //距离
     95 int gap[N]; //层结点数(用于间隙优化)
     96 int SAP(int s, int t) //源点、汇点、结点数
     97         {
     98     CLR(gap, 0);
     99     CLR(cur, 0);
    100     CLR(dis, 0);
    101     int u = pre[s] = s, maxflow = 0, aug = INT_MAX;
    102     int v;
    103     gap[0] = n;
    104     while (dis[s] < n) {
    105         bool flag = false;
    106         for (v = cur[u]; v <= n; ++v) //寻找允许弧
    107                 {
    108             if (capacity[u][v] > 0 && dis[u] == dis[v] + 1) {
    109                 flag = true;
    110                 break;
    111             }
    112         }
    113         if (flag) //找到允许弧
    114         {
    115             pre[v] = u;
    116             cur[u] = v;
    117             aug = min(aug, capacity[u][v]);
    118             u = v;
    119             if (v == t) //找到完整增广路
    120                     {
    121                 maxflow += aug;
    122                 for (v = t; v != s; v = pre[v]) //更新残留网络
    123                         {
    124                     capacity[pre[v]][v] -= aug; //正向边
    125                     capacity[v][pre[v]] += aug; //反向边
    126                 }
    127                 aug = INT_MAX;
    128                 u = s; //重新从源点寻找
    129             }
    130         } else //找不到允许弧
    131         {
    132             int mindis = n;
    133             for (v = 1; v <= n; ++v) //重新标号
    134                     {
    135                 if (capacity[u][v] && mindis > dis[v]) {
    136                     cur[u] = v;
    137                     mindis = dis[v];
    138                 }
    139             }
    140             if (--gap[dis[u]] == 0) //更新断层 + 判断是否断层(间隙优化)
    141                 break;
    142             gap[dis[u] = mindis + 1]++; //更新断层
    143             u = pre[u]; //当前弧优化
    144         }
    145     }
    146     return maxflow;
    147 }
    148 
    149 inline void addedge(int x, int y, int c) { // add an arc(x -> y, c); vertex: 0 ~ n-1;
    150     capacity[x][y] = c;
    151 }
    152 
    153 int main() {
    154     int _n, k, u, v;
    155     char tmp;
    156     cin >> _n;
    157     n = _n * 2 + 2;
    158     cin >> k;
    159     for (int i = 0; i < _n; i++) {
    160         addedge(0, i + 1, 1);
    161         addedge(_n + i + 1, n - 1, 1);
    162     }
    163     for (int i = 0; i < k; i++) {
    164         scanf("%d %d", &u, &v);
    165         addedge(u, v + _n, 1);
    166     }
    167     int sum = MaxFlow(0, n - 1);
    168 //int sum = SAP( 0, curn - 1);
    169     cout << sum << endl;
    170     return 0;
    171 }

    from kakamilan

  • 相关阅读:
    大型网游全景图制作方法
    KRPano中文教程文档PDF版本下载
    KRPANO资源分析工具下载VR-FACTORY全景图
    KRPANO资源分析工具下载网展全景图
    KRPANO资源分析工具下载720THINK全景图
    遗留代码单元测试与重构的一点小体会
    Openflow Plugin学习笔记2
    Openflow Plugin学习笔记1
    直接并不简单
    DIDM源码分析
  • 原文地址:https://www.cnblogs.com/kakamilan/p/3070139.html
Copyright © 2020-2023  润新知