BZOJ 1001: [BeiJing2006] 狼抓兔子

利用平面图的性质把最小割转化为最短路问题,大概是这样的:


太菜了。。。先是数组开太大,中间dijkstra的pair还写反了(捂脸)

/**************************************************************
    Problem: 1001
    User: will7101
    Language: C++
    Result: Accepted
    Time:1912 ms
    Memory:95340 kb
****************************************************************/
 
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <utility>
#include <queue>
using namespace std;
 
typedef long long ll; 
const int MAXV = 2200000, MAXE = 6600000, INF = 0x3f3f3f3f;
struct edge{int to, cost, next; } es[MAXE];
int head[MAXV], E, V, N, M, s, e;
 
void init(){
    memset(head, -1, sizeof(head));
}
 
inline void add2(const int &a, const int &b, const int &cost){
    es[E] = (edge) {b, cost, head[a]};
    head[a] = E++;
    es[E] = (edge) {a, cost, head[b]};
    head[b] = E++;
}
 
int d[MAXV];
  
int dijkstra(int s, int e){
    typedef pair<int, int> P;
    priority_queue<P, vector<P>, greater<P> > que;
    memset(d, 0x3f, sizeof(d));
    d[s] = 0;
    que.push(P(0, s));
    while(!que.empty()){
        P p = que.top(); que.pop();
        int u = p.second;
        if(p.first > d[u]) continue;
        for(int i = head[u]; i != -1; i = es[i].next){
            int v = es[i].to;
            if(d[v] > d[u] + es[i].cost){
                d[v] = d[u] + es[i].cost;
                que.push(P(d[v], v));
            }
        }
    }
    return d[e];
}
 
/* 
int SPFA(int s, int e){
    queue<int> que;
    memset(d, 0x3f, sizeof(d));
    d[s] = 0;
    que.push(s); vis[s] = true;
     
    while(!que.empty()){
        int u = que.front(); que.pop(); vis[u] = false;
        for(int i = head[u]; i != -1; i = es[i].next){
            int v = es[i].to, c = es[i].cost;
            if(d[v] > d[u] + c){ 
                d[v] = d[u] + c;
                if(!vis[v]){
                    que.push(v);
                    vis[v] = true;
                }
            }
        } 
    }
     
    return d[e];
}
*/
 
inline void rint(int &a){
    char c;
    while((c = getchar()) < '0' || c > '9');
    a = c - '0';
    while((c = getchar()) >= '0' && c <= '9') a = (a << 3) + (a << 1) + c - '0';
}
 
void read(){
    int sz = (N - 1) * (M - 1), c;
    s = sz * 2; e = s + 1;
    for(int i = 0; i < M - 1; i++){
        rint(c);
        add2(s, i, c);
    }
    for(int i = 1; i < N - 1; i++){
        for(int j = 0; j < M-1; j++){
            rint(c);
            add2(sz + (i - 1) * (M - 1) + j, i * (M - 1) + j, c);
        }
    }
    for(int i = 0; i < M - 1; i++){
        rint(c);
        add2(sz + (N - 2) * (M - 1) + i, e, c);
    }
//==========================================================    
    for(int i = 0; i < N - 1; i++){
        rint(c);
        add2(e, sz + i * (M - 1), c);
        for(int j = 0; j < M - 2; j++){
            scanf("%d", &c);
            add2(i * (M - 1) + j, sz + i * (M - 1) + j + 1, c);
        }
        rint(c);
        add2(i * (M - 1) + M - 2, s, c);
    }
    for(int i = 0; i < N - 1; i++){
        for(int j = 0; j < M - 1; j++){
            rint(c);
            add2(i * (M - 1) + j, sz + i * (M - 1) + j, c);
        }
    }
}
 
int main(){
//  freopen("in.txt", "r", stdin);
    scanf("%d%d", &N, &M);
    if(N == 1 && M == 1){
        printf("0\n");
        return 0;
    }
    if(N == 1){
        int ans = INF, c;
        for(int i = 0; i < M - 1; i++){
            scanf("%d", &c);
            if(ans > c) ans = c;
        }
        printf("%d\n", ans);
        return 0;
    }
    if(M == 1){
        int ans = INF, c;
        for(int i = 0; i < N - 1; i++){
            scanf("%d", &c);
            if(ans > c) ans = c;
        }
        printf("%d\n", ans);
        return 0;
    }
    init();
    read();
    printf("%d\n", dijkstra(s, e));
    return 0;
}

posted @ 2016-02-02 23:33  will7101  阅读(176)  评论(0编辑  收藏  举报