标签:line printf nbsp ret main 图片 sign gis div
这题是一个裸的网络流的题,但是本蒟蒻还是调试了半天2333.总是犯低级错误。
一开始我是用EK算法实现的。结果如下:
然后我又用Dinic算法实现了一下。
发现更慢了2333.我也不知道为啥,按道理Dinic应该比EK快的不知道到哪里去了才对。
下面是我的代码实现:
EK算法:
#include <bits/stdc++.h> using namespace std; #define re register inline long long read() { char ch = getchar(); long long x = 0, f = 1; while(ch < ‘0‘ || ch > ‘9‘) { if(ch == ‘-‘) f = -1; ch = getchar(); } while(‘0‘ <= ch && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); } return x * f; } const int N = 36000,M = 5000000; struct line { int v; int cap; int nxt; } datas [M]; int head [N],cnt = 1; inline void add (int a,int b,int c) { ++ cnt; datas [cnt].v = b; datas [cnt].cap = c; datas [cnt].nxt = head [a]; head [a] = cnt; } int s = 0,t; int n,m; inline int qlink (int x,int y) { //前部点 return x * n + y; } inline int hlink (int x,int y) { //后部点 return qlink (n,n) + qlink (x,y); } int dx [] = {0,0,1,-1},dy [] = {1,-1,0,0}; bool vis [N]; inline int dfs (int u,int flow) { vis [u] = true; //开始EK算法 if (u == t) { return flow; } for (int ptr = head [u];ptr;ptr = datas [ptr].nxt) { int v = datas [ptr].v,c = datas [ptr].cap; if (!c || vis [v]) { continue ; } int ret = dfs (v,min (flow,c)); if (!ret) { continue ; } //开始减掉自己 datas [ptr].cap -= ret; datas [ptr ^ 1].cap += ret; return ret; } return 0; } signed main(){ #ifndef ONLINE_JUDGE freopen ("shit.txt","r",stdin); #endif #ifdef ONLINE_JUDGE #endif n = read (),m = read (); t = hlink (n,n) + 1; for (int i = 1;i <= n;++ i) { for (int j = 1;j <= n;++ j) { add (qlink (i,j),hlink (i,j),1); add (hlink (i,j),qlink (i,j),0); } } for (int i = 1;i <= m;++ i) { int x = read (),y = read (); //开始连接到源点 add (s,qlink (x,y),1); add (qlink (x,y),s,0); } //开始连接周围的点 for (int i = 1;i <= n;++ i) { for (int j = 1;j <= n;++ j) { for (int k = 0;k < 4;++ k) { int x = i + dx [k],y = j + dy [k]; if (x < 1 || y < 1 || x > n || y > n) { continue ; } add (hlink (i,j),qlink (x,y),1); add (qlink (x,y),hlink (i,j),0); } } } //开始连接周围的点 for (int i = 1;i <= n;++ i) { add (hlink (i,1),t,1); add (t,hlink (i,1),0); add (hlink (1,i),t,1); add (t,hlink (1,i),0); add (hlink (n,i),t,1); add (t,hlink (n,i),0); add (hlink (i,n),t,1); add (t,hlink (i,n),0); } int t = 0; int ans = 0; while (t = dfs (s,0x3f3f3f3f)) { ans += t; memset (vis,false,sizeof vis); } if (ans >= m) { printf ("YES\n"); }else { printf ("NO\n"); } return 0; }
下面是Dinic算法
#include <bits/stdc++.h> using namespace std; #define re register inline long long read() { char ch = getchar(); long long x = 0, f = 1; while(ch < ‘0‘ || ch > ‘9‘) { if(ch == ‘-‘) f = -1; ch = getchar(); } while(‘0‘ <= ch && ch <= ‘9‘) { x = x * 10 + ch - ‘0‘; ch = getchar(); } return x * f; } const int N = 36000,M = 5000000; struct line { int v; int cap; int nxt; } datas [M]; int head [N],cnt = 1; inline void add (int a,int b,int c) { ++ cnt; datas [cnt].v = b; datas [cnt].cap = c; datas [cnt].nxt = head [a]; head [a] = cnt; } int s = 0,t; int n,m; inline int qlink (int x,int y) { //前部点 return x * n + y; } inline int hlink (int x,int y) { //后部点 return qlink (n,n) + qlink (x,y); } int dx [] = {0,0,1,-1},dy [] = {1,-1,0,0}; int d [N]; bool vis [N]; inline bool dinic () { memset (d,0,sizeof d); queue<int> q;q.push (s); d [s] = 1; while (!q.empty ()) { int u = q.front ();q.pop (); for (int ptr = head [u];ptr;ptr = datas [ptr].nxt) { int v = datas [ptr].v; if (!d [v] && datas [ptr].cap) { q.push (v); d [v] = d [u] + 1; } } } return d [t]; } int dfs (int u,int flow) { if (u == t) { return flow; } int dd = 0; for (int ptr = head [u];ptr;ptr = datas [ptr].nxt) { int v = datas [ptr].v,cap = datas [ptr].cap; if (d [v] == d [u] + 1 && cap) { int ret = dfs (v,min (cap,flow)); datas [ptr].cap -= ret; datas [ptr ^ 1].cap += ret; flow -= ret; dd += ret; if (!flow) { break ; } } } if (!dd) { d [u] = -1; } return dd; } signed main(){ #ifndef ONLINE_JUDGE freopen ("shit.txt","r",stdin); #endif #ifdef ONLINE_JUDGE #endif n = read (),m = read (); t = hlink (n,n) + 1; for (int i = 1;i <= n;++ i) { for (int j = 1;j <= n;++ j) { add (qlink (i,j),hlink (i,j),1); add (hlink (i,j),qlink (i,j),0); } } for (int i = 1;i <= m;++ i) { int x = read (),y = read (); //开始连接到源点 add (s,qlink (x,y),1); add (qlink (x,y),s,0); } //开始连接周围的点 for (int i = 1;i <= n;++ i) { for (int j = 1;j <= n;++ j) { for (int k = 0;k < 4;++ k) { int x = i + dx [k],y = j + dy [k]; if (x < 1 || y < 1 || x > n || y > n) { continue ; } add (hlink (i,j),qlink (x,y),1); add (qlink (x,y),hlink (i,j),0); } } } //开始连接周围的点 for (int i = 1;i <= n;++ i) { add (hlink (i,1),t,1); add (t,hlink (i,1),0); add (hlink (1,i),t,1); add (t,hlink (1,i),0); add (hlink (n,i),t,1); add (t,hlink (n,i),0); add (hlink (i,n),t,1); add (t,hlink (i,n),0); } int t = 0; int ans = 0; while (dinic ()) { ans += dfs (s,0x3f3f3f3f); } if (ans >= m) { printf ("YES\n"); }else { printf ("NO\n"); } return 0; }
标签:line printf nbsp ret main 图片 sign gis div
原文地址:https://www.cnblogs.com/dorbmon/p/11693261.html