您的位置:首页 > 理论基础 > 计算机网络

HDU - 2828 网络流

2017-01-27 16:58 253 查看
题目大意

  有n个灯,m个开关,由于线路乱接导致可能有多个开关对应一个灯(并联),有的灯在开关开的时候亮

  有的灯在开关关的时候亮,【每个开关最多对应两盏灯】,试找出一种开关的ON,OFF状态,使得所有灯都亮。

  (注意不要漏读黑框内的内容)

解法1:网络流

  对于一个开关有一下几种情况:

  1.开关只连向一个灯,直接设定开关点亮此灯。

  2.开关连向两个开关状态需求相同的灯,直接把开关拨到相应状态,点亮两个灯。

  3.开关连向两个需求不同冲突的灯,(只能选择两者之一点亮)。

  接下来网络流即可【注意区分n,m】

1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <vector>
5 #include <queue>
6
7 #define N 1010
8 #define INF 0x3f3f3f3f
9 #define p E[i].x
10
11 using namespace std;
12
13 int n,m,S,T,totE;
14 int sw
,g
,d
;
15 bool v
;
16 vector<int> a[2]
;
17 queue<int> q;
18
19 struct edge
20 {
21     int x,to,cap;
22 }E[200010];
23
24 void addedge(int x,int y,int cap)
25 {
26     E[++totE] = (edge){y,g[x],cap}; g[x]=totE;
27     E[++totE] = (edge){x,g[y],0};    g[y]=totE;
28 }
29
30 bool bfs()
31 {
32     memset(v,0,sizeof(v));
33     d[S]=1;
34     v[S]=1;
35     q.push(S);
36     while(!q.empty())
37     {
38         int x=q.front(); q.pop();
39         for(int i=g[x];i;i=E[i].to)
40             if(E[i].cap && !v[p])
41             {
42                 v[p]=1;
43                 d[p]=d[x]+1;
44                 q.push(p);
45             }
46     }
47     return v[T];
48 }
49
50 int dinic(int x,int flow)
51 {
52     if(x==T || !flow) return flow;
53     int f=0;
54     for(int i=g[x];i&&flow;i=E[i].to)
55         if(d[p]==d[x]+1&&E[i].cap)
56         {
57             int tmp=dinic(p,min(flow,E[i].cap));
58             f+=tmp;
59             flow-=tmp;
60             E[i].cap-=tmp;
61             E[i^1].cap+=tmp;
62         }
63     if(!f) d[x]=-1;
64     return f;
65 }
66
67 int main()
68 {
69 //    freopen("test.txt","r",stdin);
70     while(~scanf("%d%d",&n,&m))
71     {
72         memset(g,0,sizeof(g));
73         totE=1;
74         for(int i=1;i<=m;i++)
75         {
76             sw[i]=0;
77             a[0][i].clear();
78             a[1][i].clear();
79         }
80         char cmd[11];
81         for(int i=1,x,K;i<=n;i++)
82         {
83             scanf("%d",&K);
84             while(K--)
85             {
86                 scanf("%d%s",&x,cmd);
87                 int tmp;
88                 if(cmd[1]=='N') tmp=1;
89                 else tmp=0;
90                 a[tmp][x].push_back(i);
91             }
92         }
93         S=0;
94         T=n+m+1;
95         for(int i=1;i<=n;i++) addedge(i+m,T,1);
96         for(int i=1;i<=m;i++)
97         {
98             if(a[0][i].size()==1 && a[1][i].size()==1)
99             {
100                 addedge(S,i,1);
101                 sw[i]=-1;
102                 addedge(i,m+a[0][i][0],1);
103                 addedge(i,m+a[1][i][0],1);
104             }
105             else if(a[0][i].size()==2)
106             {
107                 addedge(S,i,2);
108                 sw[i]=0;
109                 addedge(i,m+a[0][i][0],1);
110                 addedge(i,m+a[0][i][1],1);
111             }
112             else if(a[1][i].size()==2)
113             {
114                 addedge(S,i,2);
115                 sw[i]=1;
116                 addedge(i,m+a[1][i][0],1);
117                 addedge(i,m+a[1][i][1],1);
118             }
119             else
120             {
121                 addedge(S,i,1);
122                 if(a[1][i].size())         sw[i]=1, addedge(i,m+a[1][i][0],1);
123                 else if(a[0][i].size()) sw[i]=0, addedge(i,m+a[0][i][0],1);
124                 else sw[i]=0;
125             }
126         }
127         int ans=0;
128         while(bfs()) ans+=dinic(S,INF);
129         if(ans<n) puts("-1");
130         else
131         {
132             for(int i=2;i<=totE;i+=2)
133             {
134                 if(E[i].cap) continue;
135                 int x=E[i^1].x, y=E[i].x;
136                 if(sw[x]!=-1) continue;
137                 //cout << x << ' ' << y-m<<endl;
138                 if(x<=m && x>=1)
139                 {
140                     if(y-m == a[0][x][0]) sw[x]=0;
141                     else sw[x]=1;
142                 }
143             }
144             for(int i=1;i<=m;i++)
145             {
146                 if(sw[i]) printf("ON%c",i==m? '\n':' ');
147                 else printf("OFF%c",i==m? '\n':' ');
148             }
149         }
150     }
151     return 0;
152 }


View Code

解法2:DLX
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: