• 网络流之补题心得


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

      网络流之板子

      

    /*  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
    ", 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:
    ", ca++);
            printf("%d
    ", 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
    ", ans);
    }
    int main() {
        int t = 1;
       // freopen("in.txt", "r", stdin);
        scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }
  • 相关阅读:
    VS中注释的使用
    VS2010中:error C2471: 无法更新程序数据库
    VS2010 MFC中在对话框上添加工具栏以及工具栏提示信息并改变图标支持256色
    CToolBar与CToolBarCtrl以及CStatusBar 与CStatusBarCtrl的区别
    error C2664: “wcscpy”: 不能将参数 1 从“LPSTR”转换为“wchar_t *”
    VS2010 MFC中的Picture控件显示图像
    VS2010 MFC中屏蔽ESC和ENTER键关闭对话框的方法
    MFC中CImageList(图形列表控件)、CTreeCtrl(树形列表控件)的简单用法
    窗口类、窗口类对象与窗口 三者之间关系——孙鑫<VC++深入详解>
    VS2010 MFC中改变static字体颜色、大小、背景颜色(自定义类),及手动关联变量的方法
  • 原文地址:https://www.cnblogs.com/gggyt/p/7204169.html
Copyright © 2020-2023  润新知