第十三周:( Sicily1402) Panic Room(c++)

来源:互联网 发布:5位电话 知乎 编辑:程序博客网 时间:2024/04/30 03:12

原题链接:http://soj.sysu.edu.cn/1402

思路:
最大流经典问题。(1)设置源点(标号为0的房间设置为源点,其他房间n的标号设置为n+1),如果房间k有入侵者(intruder),则存在一条有源点指向k的弧,且容量为c(0,k)=INF;c(k,0)=INF;(2)处理由门联通的两个房间的关系了。如果房间i和j有门且cp在i,则c(i,j)=INF;c(j,i)=1;(3)汇点t就是要保护的房间号码。计算从0到t的最大流ans。若ans>=INF,说明无法保护,否则ans为需要锁上的门的最小数量(即最大流)。

代码:

#include <iostream>#include <algorithm>#include <vector>#include <cmath>#include <cstring>using namespace std;#define N 25//顶点数#define INF 400//边的最大容量struct Node{    int to;//终点    int cap; //容量    int rev; //反向边的位置};vector<Node> v[N];void add_Node(int from,int to,int cap) {    int rev1,rev2;    rev1=v[to].size();    v[from].push_back((Node){to,cap,rev1});    rev2=v[from].size()-1;    v[to].push_back((Node){from,0,rev2});}int dfs(int s,int t,int f,bool used[]){    if(s==t)        return f;    used[s]=true;    for(int i=0;i<v[s].size();i++){        Node &tmp = v[s][i];        if(used[tmp.to]==false && tmp.cap>0){            int d=dfs(tmp.to,t,min(f,tmp.cap),used);            if(d>0){                tmp.cap-=d;                v[tmp.to][tmp.rev].cap+=d;                return d;            }//更新残余网络        }    }    return 0;}int max_flow(int s,int t){    int flow=0;    while(1){        bool used[N];        memset(used,false,sizeof(used));        int f=dfs(s,t,INF,used);        if(f==0)            return flow;        flow+=f;    }}int main(){    int testcase;    cin>>testcase;    while(testcase--){        //更新        for(int i=0;i<N;i++)            v[i].clear();        int m,end;        //end为被保护者的位置        vector<int>start;        start.clear();        cin>>m>>end;        for(int i=0;i<m;i++){            string s;            cin>>s;            if(s=="I")                start.push_back(i);            int num;            cin>>num;            int to;            for(int j=0;j<num;j++){                cin>>to;                add_Node(i+1,to+1,INF);                add_Node(to+1,i+1,1);            }        }        //把0置为起点,指向有侵入者的房间        //其他点的编号都要+1        for(int i=0;i<start.size();i++){            add_Node(0,start[i]+1,INF);            add_Node(start[i]+1,0,INF);        }        int ans;        ans=max_flow(0,end+1);        if(ans>=INF)            cout<<"PANIC ROOM BREACH"<<endl;        else            cout<<ans<<endl;    }    return 0;}
原创粉丝点击