zoukankan      html  css  js  c++  java
  • 1191: [HNOI2006]超级英雄Hero

    1191: [HNOI2006]超级英雄Hero

    链接

    分析:

      二分+网络流,二分答案,网络流判断。

      或者匈牙利,从1到n挨个匹配。

    匈牙利:0ms

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cctype>
     4 
     5 const int N = 1010;
     6 
     7 struct Edge{
     8     int to,nxt;
     9     Edge() {}
    10     Edge(int a,int b) {to = a,nxt = b;}
    11 }e[1000100];
    12 int head[N],match[N],tot;
    13 bool vis[N];
    14 int n,m;
    15 
    16 inline int read() {
    17     int x = 0,f = 1;char ch = getchar();
    18     for (; !isdigit(ch); ch=getchar()) if(ch=='-') f=-1;
    19     for (; isdigit(ch); ch=getchar()) x=x*10+ch-'0';
    20     return x * f;
    21 }
    22 bool dfs(int u) {
    23     for (int i=head[u]; i; i=e[i].nxt) {
    24         int v = e[i].to - m;
    25         if (!vis[v]) {
    26             vis[v] = true;
    27             if (!match[v] || dfs(match[v])) {
    28                 match[v] = u;
    29                 return true;
    30             }
    31         }
    32     }
    33     return false;
    34 }
    35 int main () {
    36     n = read(),m = read();
    37     for (int i=1; i<=m; ++i) {
    38         int x = read() + 1,y = read() + 1;
    39         e[++tot] = Edge(x+m,head[i]);head[i] = tot;
    40         e[++tot] = Edge(y+m,head[i]);head[i] = tot;
    41     }
    42     int ans = 0;
    43     for (int i=1; i<=m; ++i) {
    44         memset(vis,false,sizeof(vis));
    45         if (dfs(i)) ans++;
    46         else break;
    47     }
    48     printf("%d",ans);
    49     return 0;
    50 }
    View Code

    网络流:72ms

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cmath>
     5 #include<iostream>
     6 #include<cctype>
     7  
     8 using namespace std;
     9  
    10 const int N = 5010;
    11  
    12 inline int read() {
    13     int x = 0,f = 1;char ch=getchar();
    14     for (; !isdigit(ch); ch=getchar()) if(ch=='-')f=-1;
    15     for (; isdigit(ch); ch=getchar()) x=x*10+ch-'0';
    16     return x*f;
    17 }
    18 struct Edge{
    19     int to,nxt,c;
    20     Edge() {}
    21     Edge(int x,int y,int z) {to = x,c = y,nxt = z;}
    22 }e[100010];
    23 int head[N],dis[N],cur[N],q[N],a[N],b[N];
    24 int L,R,tot,S,T,n,m;
    25  
    26 void add_edge(int u,int v,int w) {
    27     e[++tot] = Edge(v,w,head[u]);head[u] = tot;
    28     e[++tot] = Edge(u,0,head[v]);head[v] = tot;
    29 }
    30 bool bfs() {
    31     for (int i=1; i<=T; ++i) cur[i] = head[i],dis[i] = -1;
    32     L = 1;R = 0;
    33     q[++R] = S;
    34     dis[S] = 0;
    35     while (L <= R) {
    36         int u = q[L++];
    37         for (int i=head[u]; i; i=e[i].nxt) {
    38             int v = e[i].to;
    39             if (dis[v] == -1 && e[i].c > 0) {
    40                 dis[v] = dis[u] + 1;
    41                 q[++R] = v;
    42                 if (v == T) return true;
    43             }
    44         }
    45     }
    46     return false;
    47 }
    48 int dfs(int u,int flow) {
    49     if (u == T) return flow;
    50     int used = 0,tmp;
    51     for (int i=cur[u]; i; i=e[i].nxt) {
    52         int v = e[i].to;
    53         if (dis[v] == dis[u] + 1 && e[i].c > 0) {
    54             tmp = dfs(v,min(flow-used,e[i].c));
    55             if (tmp) {
    56                 e[i].c -= tmp;e[i^1].c += tmp;
    57                 used += tmp;
    58                 if (used == flow) break;
    59             }
    60         }
    61     }
    62     if (used != flow) dis[u] = -1;
    63     return used;
    64 }
    65 bool check(int x) {
    66     memset(head,0,sizeof(head));
    67     tot = 1;
    68     S = x + n + 1,T = x + n + 2;
    69     for (int i=1; i<=x; ++i) {   
    70         add_edge(i+n,a[i],1);
    71         add_edge(i+n,b[i],1);   
    72         add_edge(S,i+n,1);      
    73     }
    74     for (int i=1; i<=n; ++i) add_edge(i,T,1);
    75     int ans = 0;
    76     while (bfs()) 
    77     ans += dfs(S,1e9);
    78     return ans==x;
    79 }
    80 int main() {
    81     n = read(),m = read();
    82     for (int i=1; i<=m; ++i) {
    83         a[i] = read()+1,b[i] = read()+1;
    84     }
    85     int L = 1,R = m,ans = 1;
    86     while (L <= R) {
    87         int mid = (L + R) / 2;
    88         if (check(mid)) ans = mid,L = mid + 1;
    89         else R = mid - 1;
    90     }
    91     cout << ans;
    92     return 0;
    93 }
    View Code
  • 相关阅读:
    Flink 的datastreamAPI 以及function函数的调用,性能调优
    Spark Shuffle原理、Shuffle操作问题解决和参数调优
    Spark学习之JavaRdd
    Redis学习笔记--Redis数据过期策略详解==转
    Elasticsearch 数据搜索篇·【入门级干货】===转
    HBase二级索引的设计(案例讲解)
    C中指针符*和取址符&
    java 中,如何获取文件的MD5值呢?如何比较两个文件是否完全相同呢?
    Mysql数据库的加密与解密
    Lucene 分词
  • 原文地址:https://www.cnblogs.com/mjtcn/p/9128313.html
Copyright © 2011-2022 走看看