觉得网络流是很神奇的东西,只要把边建出来了,其他的一下子就解决啦(●'◡'●)
网络流之板子
/* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 1000+10; const ll maxm = 1e7; const int modd = 10000007; const int INF = 1<<30; const db eps = 1e-9; struct Edge { int u, v, cap, flow; }e[maxn*40]; vector<int>G[maxn]; int d[maxn], cur[maxn]; bool vis[maxn]; int m, n, cnt; int s, t; void init() { for (int i=0; i<=200; i++) { G[i].clear(); } cnt=0; } void add(int u, int v, int cap, int f) { e[cnt].u=u, e[cnt].cap=cap, e[cnt].flow=f, e[cnt].v=v; } void Addedge(int u, int v, int cost) { add(u, v, cost, 0); G[u].push_back(cnt++); add(v, u, 0, 0); G[v].push_back(cnt++); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int>q; q.push(s); vis[s]=1; d[s]=0; while(!q.empty()) { int v=q.front(); q.pop(); for (int i=0; i<G[v].size(); i++) { Edge &te=e[G[v][i]]; if (!vis[te.v] && te.cap>te.flow) { vis[te.v]=1; d[te.v]=d[v]+1; q.push(te.v); } } } return vis[t]; } int dfs(int x, int a) { if (x==t||a==0) return a; int flow=0, f; for (int &i=cur[x]; i<G[x].size(); i++) { Edge &te=e[G[x][i]]; if (d[x]+1==d[te.v] && (f=dfs(te.v, min(a, te.cap-te.flow)))>0) { te.flow+=f; e[G[x][i]^1].flow -= f; flow += f; a -= f; if (a == 0) break; } } return flow; } int Dinic() { int flow=0; while(BFS()) { memset(cur, 0, sizeof(cur)); flow+=dfs(s, INF); } return flow; } void solve() { while(scanf("%d%d", &m, &n)!=EOF) { init(); for (int i=0; i<m; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); Addedge(a, b, c); } s=1, t=n; int ans=Dinic(); printf("%d\n", ans); } } int main() { int t = 1; //freopen("in.txt", "r", stdin); //scanf("%d", &t); while(t--) solve(); return 0; }
第一眼看到这个题的时候我是很蒙蔽的,这个咋做啊??完全不会建边啊
可是看了别人的之后发现 哦~这样啊,一下子就变得好简单。还是做题做少了,思考少了
思路:首先找一个超级原点和超级汇点分别与狼和羊相连,然后在对每个格子和他的上下左右建边,这样就好啦。
(ง •_•)ง加油
/* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 4e4+10; const ll maxm = 1e7; const int modd = 10000007; const int INF = 1<<30; const db eps = 1e-9; struct Edge { int u, v, cap, flow; }e[maxn*4]; vector<int>G[maxn]; int d[maxn], cur[maxn]; bool vis[maxn]; int m, n, cnt; int s, t; int ca=1; void init() { for (int i=0; i<=maxn; i++) { G[i].clear(); } cnt=0; } void add(int u, int v, int cap, int f) { e[cnt].u=u, e[cnt].cap=cap, e[cnt].flow=f, e[cnt].v=v; } void Addedge(int u, int v, int cost) { add(u, v, cost, 0); G[u].push_back(cnt++); add(v, u, 0, 0); G[v].push_back(cnt++); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int>q; q.push(s); vis[s]=1; d[s]=0; while(!q.empty()) { int v=q.front(); q.pop(); for (int i=0; i<G[v].size(); i++) { Edge &te=e[G[v][i]]; if (!vis[te.v] && te.cap>te.flow) { vis[te.v]=1; d[te.v]=d[v]+1; q.push(te.v); } } } return vis[t]; } int dfs(int x, int a) { if (x==t||a==0) return a; int flow=0, f; for (int &i=cur[x]; i<G[x].size(); i++) { Edge &te=e[G[x][i]]; if (d[x]+1==d[te.v] && (f=dfs(te.v, min(a, te.cap-te.flow)))>0) { te.flow+=f; e[G[x][i]^1].flow -= f; flow += f; a -= f; if (a == 0) break; } } return flow; } int Dinic() { int flow=0; while(BFS()) { memset(cur, 0, sizeof(cur)); flow+=dfs(s, INF); } return flow; } void solve() { while(scanf("%d%d", &n, &m)!=EOF) { init(); s=0, t=n*m+1; for (int i=1; i<=n; i++) { for (int j=1; j<=m; j++) { int x; scanf("%d", &x); if (x==2) { Addedge((i-1)*m+j, t, INF); } if (x==1) { Addedge(s, (i-1)*m+j, INF); } if (i!=1) { Addedge((i-1)*m+j, (i-2)*m+j, 1); } if (i!=n) { Addedge((i-1)*m+j, (i)*m+j, 1); } if (j!=1) { Addedge((i-1)*m+j, (i-1)*m+j-1, 1); } if (j!=m) { Addedge((i-1)*m+j, (i-1)*m+j+1, 1); } } } int ans=Dinic(); printf("Case %d:\n", ca++); printf("%d\n", ans); } } int main() { int t = 1; //freopen("in.txt", "r", stdin); //scanf("%d", &t); while(t--) solve(); return 0; }
这道题和hdu3046简直一模一样好吗!连建模都差不多!!!
题意:给你一个地图,僵尸?可以从任意不是‘X'的地方进来,’X‘是绝对安全的地方!!
问你怎么样隔断才能保护所有的’D'点。 四不四和上面的一模一样!
也是找个超级原点和超级汇点然后biu的一下就解决啦。(ง •_•)ง
/* gyt Live up to every day */ #include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<stack> #include<cstring> #include<queue> #include<set> #include<string> #include<map> #include <time.h> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 4e4+10; const ll maxm = 1e7; const int modd = 10000007; const int INF = 1<<30; const db eps = 1e-9; struct Edge { int u, v, cap, flow; }e[maxn*10]; vector<int>G[maxn]; int d[maxn], cur[maxn]; char ma[200][200]; bool vis[maxn]; int m, n, cnt; int s, t; int ca=1; int dir[][2]={{1,0},{0,1},{-1,0},{0,-1}}; void init() { for (int i=0; i<maxn; i++) { G[i].clear(); } cnt=0; } void add(int u, int v, int cap, int f) { e[cnt].u=u, e[cnt].cap=cap, e[cnt].flow=f, e[cnt].v=v; } void Addedge(int u, int v, int cost) { add(u, v, cost, 0); G[u].push_back(cnt++); add(v, u, 0, 0); G[v].push_back(cnt++); } bool BFS() { memset(vis, 0, sizeof(vis)); queue<int>q; q.push(s); vis[s]=1; d[s]=0; while(!q.empty()) { int v=q.front(); q.pop(); for (int i=0; i<G[v].size(); i++) { Edge &te=e[G[v][i]]; if (!vis[te.v] && te.cap>te.flow) { vis[te.v]=1; d[te.v]=d[v]+1; q.push(te.v); } } } return vis[t]; } int dfs(int x, int a) { if (x==t||a==0) return a; int flow=0, f; for (int &i=cur[x]; i<G[x].size(); i++) { Edge &te=e[G[x][i]]; if (d[x]+1==d[te.v] && (f=dfs(te.v, min(a, te.cap-te.flow)))>0) { te.flow+=f; e[G[x][i]^1].flow -= f; flow += f; a -= f; if (a == 0) break; } } return flow; } int Dinic() { int flow=0; while(BFS()) { memset(cur, 0, sizeof(cur)); flow+=dfs(s, INF); } return flow; } bool safe(int x, int y) { if (x<0||x>(n+1)||y<0||y>(m+1)) return 0; return 1; } void solve() { init(); scanf("%d%d", &n, &m); for (int i=0; i<=n+1; i++) { for (int j=0; j<=m+1; j++) { ma[i][j]='.'; } } for (int i=1; i<=n; i++) { scanf("%s", ma[i]+1); } s=(n+3)*(m+3)+1, t=s+1; for (int i=0; i<=n+1; i++) { for (int j=0; j<=m+1; j++) { if (i==0||j==0||i==n+1||j==m+1) { Addedge(s, i*(m+2)+j, INF); } if (ma[i][j]=='D') { Addedge(i*(m+2)+j,t, INF); } if (ma[i][j]!='X') { for (int k=0; k<4; k++) { int xx=i+dir[k][0], yy=j+dir[k][1]; if (safe(xx,yy)) { if (ma[xx][yy]!='X') { Addedge(i*(m+2)+j, xx*(m+2)+yy, 1); } } } } } } int ans=Dinic(); printf("%d\n", ans); } int main() { int t = 1; // freopen("in.txt", "r", stdin); scanf("%d", &t); while(t--) solve(); return 0; }