HDU 3035 War (对偶图转最短路)

来源:互联网 发布:查live网络电视直播 编辑:程序博客网 时间:2024/06/05 03:44

题目地址
题意:给你一个方块图,让你求出最少割掉多少代价的边才能使得(0,0)到不了(n,m)?
提示:英语太差了,看了图才搞懂这个是怎么输入的,前n+1行是告诉每个方格上边每条边的代价,中间n行是告诉你每个方格左右的边的代价,最后2*n行是告诉你每个方格中斜边的代价,看这个图就好理解了。
说明
思路:就是套对偶图转最短路去求全局最小割,只要了解我之前的那个博客就好了。
吐槽:因为是刚刚接触这类的题目,所以我参考了别人的博客。当时我看到他说因为他的define找了好久的bug,我当时还在想哪里有问题,然后我觉得他的这个define写的蛮好的,我就决定在我的代码中用这个去定义那4个块

#define U( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 0 )  //定义4个块#define D( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 1 )  #define L( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 2 )  #define R( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 3 )  

但是我觉得他的为什么要加这么多括号,于是在我代码上写的是这种的了

#define U( i , j ) ( ( ( i * m + j ) * 4 ) + 0 )  //定义4个块#define D( i , j ) ( ( ( i * m + j ) * 4 ) + 1 )  #define L( i , j ) ( ( ( i * m + j ) * 4 ) + 2 )  #define R( i , j ) ( ( ( i * m + j ) * 4 ) + 3 )  

就因为这个决定我花了一天的时间去找bug,每个地方都改过了,就是一直连样例都过不了,但是因为这个是从他那里写的,我就一直没有看,所以一直都没有找到,我最后晚上决定对一遍代码,从头开始我才发现这里有点不同,改了就A了。|*´Å`)ノ 一定要注意define里面的变量要加括号。
这题是卡了STL里面的队列的。

#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 1000010#define M 4000010#define LL __int64#define inf 0x7f7f7f7f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1#define U( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 0 )  //定义4个块#define D( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 1 )  #define L( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 2 )  #define R( i , j ) ( ( ( ( i ) * m + ( j ) ) << 2 ) + 3 )  using namespace std;const LL mod = 1000000007;int head[N], cnt;bool vis[N];int len[N];struct node {    int to, len;    int next;}edge[M];int Q[N], heads, tail;struct SPFA {    void init() {        memset(head, -1, sizeof(head));        cnt = 0;    }    void addyes(int a, int b, int c) {        edge[cnt].to = b;        edge[cnt].len = c;        edge[cnt].next = head[a];        head[a] = cnt++;    }    void addno(int a, int b, int c) {        addyes(a, b, c);        addyes(b, a, c);    }    /*int spfa(int s, int t) {        memset(vis, false, sizeof(vis));        memset(len, inf, sizeof(len));        len[s] = 0;        vis[s] = true;        queue<int> q;        q.push(s);        while (!q.empty()) {            int u = q.front();            q.pop();            vis[u] = false;            for (int i = head[u]; ~i; i = edge[i].next) {                int v = edge[i].to;                int dis = edge[i].len;                if (len[v] > len[u] + dis) {                    len[v] = len[u] + dis;                    if (!vis[v]) {                        q.push(v);                        vis[v] = true;                    }                }            }        }        return len[t];    }*/    int spfa(int s,int t) {        memset(vis, false, sizeof(vis));        memset(len, inf, sizeof(len));        heads = tail = 0;        len[s] = 0;        Q[tail++] = s;        vis[s] = true;        while (heads != tail) {            int u = Q[heads++];            if (heads == N)                heads = 0;            vis[u] = false;            for (int i = head[u]; ~i; i = edge[i].next) {                int v = edge[i].to;                if (len[v] > len[u] + edge[i].len) {                    len[v] = len[u] + edge[i].len;                    if (!vis[v]) {                        vis[v] = true;                        if (len[v] < len[Q[heads]]) {                            if (heads == 0)                                Q[heads = N - 1] = v;                            else                                Q[--heads] = v;                        }                        else {                            Q[tail++] = v;                            if (tail == N)                                tail = 0;                        }                    }                }            }        }        return len[t];    }}Spfa;int main() {    int n, m;    int num;    while (~scanf("%d %d", &n, &m)) {        Spfa.init();        int s = n * m * 4;        int t = s + 1;        for (int i = 0; i <= n; i++) {            for (int j = 0; j < m; j++) {                scanf("%d", &num);                if (i == 0) {                    Spfa.addno(U(i, j), t, num);                }                else if (i == n) {                    Spfa.addno(s, D(i - 1, j), num);                }                else {                    Spfa.addno(U(i, j), D(i - 1, j), num);                }            }        }        for (int i = 0; i < n; i++) {            for (int j = 0; j <= m; j++) {                scanf("%d", &num);                if (j == 0) {                    Spfa.addno(s, L(i, j), num);                }                else if (j == m) {                    Spfa.addno(R(i, j - 1), t, num);                }                else {                    Spfa.addno(R(i, j - 1), L(i, j), num);                }            }        }        for (int i = 0; i < 2 * n; i++) {            for (int j = 0; j < 2 * m; j++) {                scanf("%d", &num);                int x = i >> 1;                int y = j >> 1;                if ((i & 1) == 0 && (j & 1) == 0)                    Spfa.addno(L(x, y), U(x, y), num);                else if ((i & 1) == 0 && (j & 1) == 1)                    Spfa.addno(U(x, y), R(x, y), num);                else if ((i & 1) == 1 && (j & 1) == 0)                    Spfa.addno(L(x, y), D(x, y), num);                else if ((i & 1) == 1 && (j & 1) == 1)                    Spfa.addno(D(x, y), R(x, y), num);            }        }        printf("%d\n", Spfa.spfa(s, t));    }    return 0;}
原创粉丝点击