[洛谷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 }
原文地址:https://www.cnblogs.com/skylee03/p/7257086.html