gggyt  
没谁离不开谁

  觉得网络流是很神奇的东西,只要把边建出来了,其他的一下子就解决啦(●'◡'●)

  网络流之板子

  

/*  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;
}

  HDU - 3046

  第一眼看到这个题的时候我是很蒙蔽的,这个咋做啊??完全不会建边啊

  可是看了别人的之后发现 哦~这样啊,一下子就变得好简单。还是做题做少了,思考少了

  思路:首先找一个超级原点和超级汇点分别与狼和羊相连,然后在对每个格子和他的上下左右建边,这样就好啦。

  (ง •_•)ง加油

/*  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;
}

  UVALive - 647 

  这道题和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;
}

 

posted on 2017-07-19 09:58  gggyt  阅读(151)  评论(0编辑  收藏  举报