uva 11380 Down Went The Titanic

来源:互联网 发布:在哪儿玩网络创世纪 编辑:程序博客网 时间:2024/04/30 21:14
解题思路:此题其实是最大流类型中最基础的一类问题,关键就在于如何去建图,建图的思路就是在起点左侧标一个超级起点,终点右侧标一个超级汇点,根据中间点的连接情况不断的往中间加边,最后求出起点到终点的最大流既是答案,可以说是一道模板题,一定要好好体会中间构图的思想。
//模板题 好好理解
/* By QMJ */#include <iostream>#include <cstdio>#include <queue>#include <cstring>#define inf 0x3f3f3f3f#define maxn 50000using namespace std;struct Edge{    int u,v,c,next;}e[maxn];int path[maxn],head[maxn];char ch[35][35];int maxflow,offflow,cnt,x,y,p,from,to;bool vis[maxn];int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};void initial(){    memset(head,-1,sizeof(head));    cnt=0;    maxflow=0;}void add(int u,int v,int c){    e[cnt].u=u;    e[cnt].v=v;    e[cnt].c=c;    e[cnt].next = head[u];    head[u]=cnt++;    e[cnt].u=v;    e[cnt].v=u;    e[cnt].c=0;    e[cnt].next=head[v];    head[v]=cnt++;}int fin(int a,int b){    return a*y+b+1;}int fout(int a,int b){    return x*y+a*y+b+1;}////build the graphvoid process(){    int s=0,t=2*x*y+1;    from =s,to=t;    for(int i=0;i<x;i++){        for(int j=0;j<y;j++){            if(ch[i][j]=='~') continue;            for(int k=0;k<4;k++){                int nx,ny;                nx=i+dir[k][0],ny=j+dir[k][1];                if(nx<0||nx>=x||ny<0||ny>=y)continue;                add(fout(i,j),fin(nx,ny),inf);            }            if(ch[i][j]=='*') add(s,fout(i,j),1);            else if(ch[i][j]=='.') add(fin(i,j),fout(i,j),1);            else if(ch[i][j]=='@') add(fin(i,j),fout(i,j),inf);            else if(ch[i][j]=='#') {                add(fin(i,j),fout(i,j),inf);                add(fout(i,j),t,p);            }        }    }}bool bfs(){    int s=from,d;    queue<int> q;    q.push(s);    memset(vis,false,sizeof(vis));    while(!q.empty()){        s=q.front(),q.pop();        vis[s]=true;        for(int i=head[s];i!=-1;i=e[i].next){            d=e[i].v;            if(!vis[d]&&e[i].c>0){                q.push(d);                vis[d]=true;                path[d]=i;                if(d==to) return true;            }        }    }    return false;}void solve(){    while(bfs()){        offflow=inf;        for(int i=to;i!=from;i=e[path[i]].u){            offflow=min(offflow,e[path[i]].c);        }        for(int i=to;i!=from;i=e[path[i]].u){            e[path[i]].c-=offflow;            e[path[i]^1].c+=offflow;        }        maxflow+=offflow;    }    printf("%d\n",maxflow);}int main(){    while(cin>>x>>y>>p){        initial();        getchar();        for(int i=0;i<x;i++){            gets(ch[i]);        }        process();        solve();    }    return 0;}

0 0