uva 753 A Plug for UNIX(最大流)

来源:互联网 发布:小区网络监控方案 编辑:程序博客网 时间:2024/06/05 04:59

题意: n个插座,下面n行是每个插座的类型

         m个电器,下面m行每行两个单词分别是电器的名字和插头类型

         k个转换器,下面k行每行两个单词,分别表示转换器的入口类型和插头类型

每种转换器的个数是无限的,可以多个转换器相连。         求最小不能插上去的电器的数量。


分析:

最大流。

定义源点和汇点,源点和设备相连,容量为1.

汇点和插头相连,容量也为1.

插头和设备相连,容量也为1.

可转换插头相连,容量也为inf(因为插头有无限个)   其实我使用Floyd求出设备可以连哪些插座,加一条cap为1的边。(这样建图略麻烦)


因为大量使用stl  这题用了60ms。后面还用了c++11的特性。



#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<cctype>#include<set>#include<map>#include<queue>#include<stack>#include<iomanip>#include<sstream>#include<limits>#define ll long long#define inf 0x3f3f3f3fusing namespace std;#define INF 0x7fffffffconst int maxn = 1e3+10;struct Edge{    int to , cap,rev;  // rev反向边};vector<Edge>G[maxn];int level[maxn],iter[maxn];  // 顶点到源点的标号   当前弧void add_edge(int from,int to,int cap) //cap容量{    G[from].push_back((Edge){to,cap,G[to].size()});    G[to].push_back((Edge){from,0,G[from].size()-1 });}void bfs(int s) // 分层{    memset(level,-1,sizeof(level));    queue<int>que;    level[s] = 0;    que.push(s);    while(!que.empty())    {        int v = que.front();que.pop();        for(int i = 0; i < G[v].size(); i++)        {            Edge &e = G[v][i];            if (e.cap>0 && level[e.to] < 0)            {                level[e.to] = level[v]+1;                que.push(e.to);            }        }    }}int dfs(int v, int t, int f) //寻增广路{    if (v==t) return f;    for(int &i = iter[v]; i < G[v].size(); i++)    {        Edge &e = G[v][i];        if (e.cap > 0 && level[v] < level[e.to])        {            int d = dfs(e.to , t, min(f,e.cap));            if (d > 0)            {                e.cap -= d;                G[e.to][e.rev].cap += d;                return d;            }        }    }    return 0;}int max_flow(int s, int t) // s到t最大流{    int flow = 0;    for(;;)    {        bfs(s);        if (level[t] < 0) return flow;        memset(iter,0,sizeof(iter));        int f;        while((f = dfs(s,t,INF)) > 0) { flow += f;}    }}map<string, int> IDT;set<string> plug;map<string, int> device;bool f[maxn][maxn];string s1,s2;int main(){#ifdef LOCALfreopen("C:\\Users\\lanjiaming\\Desktop\\acm\\in.txt","r",stdin);//freopen("output.txt","w",stdout);#endifios_base::sync_with_stdio(0);    int T,n,m,kase = 0;    cin>>T;    while(T--)    {        IDT.clear(); plug.clear();device.clear();        memset(f,false,sizeof(f));        if (kase) cout<<endl;        kase++;        cin>>n;        for(int i = 1; i <= n; i++)        {            cin>>s1;            plug.insert(s1);            IDT[s1] = IDT.size() - 1;        }        cin>>m;        for(int i = 1; i <= m; i++)        {            cin>>s1>>s2;            device[s2]++;            if (IDT.count(s2)==0)  IDT[s2] = IDT.size() - 1;        }         int s = 0,t = n+m+1;        for(int i= 0; i <= n+m+1; i++) G[i].clear();        for (int i = 1; i <= m; i++) add_edge(s,i,1);        for (int i = 1+m; i < 1+m+n; i++) add_edge(i,t,1);        int k;        cin>>k;        for (int i = 0; i < k; i++)        {            cin>>s1>>s2;            if (IDT.count(s1) == 0) IDT[s1] = IDT.size() - 1;            if (IDT.count(s2) == 0) IDT[s2] = IDT.size() - 1;            f[IDT[s1]][IDT[s2]] = 1;        }            int N = IDT.size();            for (int i = 0; i < N ; i++) f[i][i] = 1;            for (int kk = 0; kk < N ; kk++)                for (int i = 0; i < N ; i++)                    for (int j = 0; j < N ; j++)                        f[i][j] = f[i][j] || (f[i][kk] && f[kk][j]);        int idx = 1;        for (auto i: device)        {            vector<int> v;            int num = IDT[i.first];            if (plug.count(i.first)) v.push_back(IDT[i.first] + m + 1);            for (int j = 0; j < N; j++)              if (j != num && f[num][j] && j < n) v.push_back(j + m + 1);            for (int j = 0; j < i.second; idx++, j++)                for (auto kk: v) add_edge(idx, kk,1);        }        cout<<m-max_flow(s,t)<<endl;    }    return 0;}



0 0