zoukankan      html  css  js  c++  java
  • [洛谷1231]教辅的组成

    思路:

    最大流跑三分图匹配,注意每本书只能用一次,所以把每本书拆成两个点,连一条边。
    不能直接用EdmondsKarp算法,也不能直接用不加优化的Dinic算法,这样会TLE7个点。
    本题正解是Dinic算法加上当前弧优化。

     1 #include<queue>
     2 #include<cstdio>
     3 #include<cctype>
     4 #include<vector>
     5 #include<cstring>
     6 #include<cstdlib>
     7 inline int getint() {
     8     char ch;
     9     while(!isdigit(ch=getchar()));
    10     int x=ch^'0';
    11     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    12     return x;
    13 }
    14 const int inf=0x7fffffff;
    15 int s,t;
    16 struct Edge {
    17     int from,to;
    18     bool remain;
    19 };
    20 const int E=1400000,V=400002;
    21 Edge e[E];
    22 std::vector<int> g[V];
    23 int sz=0;
    24 inline void add_edge(const int u,const int v,const bool w) {
    25     e[sz]=(Edge){u,v,w};
    26     g[u].push_back(sz);
    27     sz++;
    28 }
    29 int d[V];
    30 inline void SPFA() {
    31     d[s]=0;
    32     for(register int i=1;i<=t;i++) d[i]=inf;
    33     std::queue<int> q;
    34     q.push(s);
    35     while(!q.empty()) {
    36         int x=q.front();
    37         q.pop();
    38         if(x==t) return;
    39         for(register unsigned i=0;i<g[x].size();i++) {
    40             Edge &y=e[g[x][i]];
    41             if((d[x]+1<d[y.to])&&y.remain) {
    42                 d[y.to]=d[x]+1;
    43                 q.push(y.to);
    44             }
    45         }
    46     }
    47 }
    48 unsigned cur[V];
    49 bool Augment(const int x,const bool remain) {
    50     if(x==t) return remain;
    51     for(unsigned &i=cur[x];i<g[x].size();i++) {
    52         Edge &y=e[g[x][i]];
    53         if((d[y.to]>d[x])&&y.remain) {
    54             if(Augment(y.to,std::min(remain,y.remain))) {
    55                 e[g[x][i]].remain^=true;
    56                 e[g[x][i]^1].remain^=true;
    57                 return true;
    58             }
    59         }
    60     }
    61     return false;
    62 }
    63 inline int Dinic() {
    64     int maxflow=0;
    65     for(SPFA();d[t]!=inf;SPFA()) {
    66         memset(cur,0,sizeof cur);
    67         while(Augment(s,true)) maxflow++;
    68     }
    69     return maxflow;
    70 }
    71 int main() {
    72     int n2=getint(),n1=getint(),n3=getint();
    73     s=0,t=n1+n2*2+n3+1;
    74     for(register int i=1;i<=n1;i++) {
    75         add_edge(s,i,true);
    76         add_edge(i,s,false);
    77     }
    78     for(register int m=getint();m;m--) {
    79         int a=getint(),b=getint();
    80         add_edge(b,n1+a,true);
    81         add_edge(n1+a,b,false);
    82     }
    83     for(register int i=1;i<=n2;i++) {
    84         add_edge(n1+i,n1+n2+i,true);
    85         add_edge(n1+n2+i,n1+i,false);
    86     }
    87     for(register int m=getint();m;m--) {
    88         int a=getint(),b=getint();
    89         add_edge(n1+n2+a,n1+n2*2+b,true);
    90         add_edge(n1+n2*2+b,n1+n2+a,false);
    91     }
    92     for(register int i=1;i<=n3;i++) {
    93         add_edge(n1+n2*2+i,t,true);
    94         add_edge(t,n1+n2*2+i,false);
    95     }
    96     printf("%d
    ",Dinic());
    97     return 0;
    98 }
  • 相关阅读:
    (转)一个JavaWeb项目开发总结
    (转)JAVA之桥接模式
    (转)Singleton 单例模式(懒汉方式和饿汉方式)
    (备忘)android模拟器摄像头模拟
    (原创)android中使用相机的两种方式
    (转)android中颜色矩阵colormatrix
    android中paint的setXfermode属性
    【贾志豪NOIP模拟题】慰问员工 cheer 【最小生成树】【对边权值的一些处理】
    【洛谷1340】兽径管理(最小生成树 Kruskal)(sort的一些技巧)【2012福建省信息学奥林匹克CCF NOIP夏令营第05天训练】
    【CSP2019】【洛谷5657】格雷码
  • 原文地址:https://www.cnblogs.com/skylee03/p/7257086.html
Copyright © 2011-2022 走看看