题意:双核电脑上有N个模块,可以在核A或核B上运行,运行时间不同.此外有M组数据(u,v,w)表示从模块u与模块v之间传输,如果模块u和模块v在同一个核心里运行,则传输不需要时间,否则需w时间,求用最少时间使这N个模块在电脑上运行,并完成数据传输.
分析:
一开始真的不知道使用网络流。看到分配成两部分的题,就要想到网络流最小割的问题。
最小割.建图:N个模块当作N个点,从源点到这N个点,容量为在A核运行时间,再连一汇点,容量为在B核运行时间,另外,M组数据传输(u,v,w),连u->v(w),v->u(w);
dinic+邻接表。TLE了。这是为什么呢?以后还得考虑啊。

View Code
1 #include <iostream>
2 #include <stdio.h>
3 #include <memory.h>
4 #include <list>
5 using namespace std;
6 const int maxp=20005;
7 const int maxe=200205;
8 const int maxdata=(1<<30);
9 int p,e;
10 struct edge
11 {
12 int u;
13 int v;
14 int w;
15 int next;
16 int rnum;
17 }edge[1000000];
18 typedef struct
19 {
20 int pre;
21 }pp;
22 pp point[maxp];
23 bool use[maxp];
24 int level[maxp];
25
26 void Init()
27 {
28 scanf("%d%d",&p,&e);
29 p=p+2;
30 int i;
31 for(i=0;i<p;i++)
32 point[i].pre=-1;
33
34 int wl,wr;
35 int index=1;
36 for(i=1;i<=p-2;i++)
37 {
38 scanf("%d%d",&wl,&wr);
39 edge[index].u=0;
40 edge[index].v=i;
41 edge[index].w=wl;
42 edge[index].rnum=index+1;
43 edge[index].next=point[0].pre;
44 point[0].pre=index;
45 index++;
46 edge[index].u=i;
47 edge[index].v=0;
48 edge[index].w=0;
49 edge[index].rnum=index-1;
50 edge[index].next=point[i].pre;
51 point[i].pre=index;
52 index++;
53
54 edge[index].u=i;
55 edge[index].v=p-1; //end point
56 edge[index].w=wr;
57 edge[index].rnum=index+1;
58 edge[index].next=point[i].pre;
59 point[i].pre=index;
60 index++;
61 edge[index].u=p-1;
62 edge[index].v=i;
63 edge[index].w=0;
64 edge[index].rnum=index-1;
65 edge[index].next=point[p-1].pre;
66 point[p-1].pre=index;
67 index++;
68 }
69 int u,v,w;
70 for(i=1;i<=e;i++)
71 {
72 scanf("%d%d%d",&u,&v,&w);
73 edge[index].u=u;
74 edge[index].v=v;
75 edge[index].w=w;
76 edge[index].rnum=index+1;
77 edge[index].next=point[u].pre;
78 point[u].pre=index;
79 index++;
80 edge[index].u=v;
81 edge[index].v=u;
82 edge[index].w=w;
83 edge[index].rnum=index-1;
84 edge[index].next=point[v].pre;
85 point[v].pre=index;
86 index++;
87 }
88 }
89
90 bool bfs()
91 {
92 int i;
93 for(i=0;i<p;i++)
94 {
95 level[i]=maxdata;
96 use[i]=false;
97 }
98
99 list<int> l;
100 l.clear();
101 level[0]=0;
102 use[0]=true;
103 l.push_back(0);
104 int t;
105 bool flag=false;
106 while(!l.empty())
107 {
108 t=l.front();
109 l.pop_front();
110 if(t==p-1)
111 flag=true;
112 for(i=point[t].pre;i!=-1;i=edge[i].next)
113 {
114 int w=edge[i].w;
115 int v=edge[i].v;
116 if(w!=0 && !use[v])
117 {
118 level[v]=level[t]+1;
119 use[v]=true;
120 l.push_back(v);
121 }
122 }
123 }
124 return flag;
125 }
126
127 int Outdegree(int u)
128 {
129 int i;
130 for(i=point[u].pre;i!=-1;i=edge[i].next)
131 {
132 int w=edge[i].w;
133 int v=edge[i].v;
134 if(w!=0 && level[v]==level[u]+1)
135 return i;
136 }
137 return 0;
138 }
139
140 int Dinic()
141 {
142 int sum=0,cf,last;
143 int start=0;
144 int u;
145 int index;
146 list<int> s;
147 list<int> e;
148 list<int>::iterator it;
149 while(bfs())
150 {
151 s.clear();
152 s.push_back(start);
153 e.clear();
154 while(Outdegree(start)>0)
155 {
156 u=s.back();
157 if(u!=p-1)
158 {
159 if((index=Outdegree(u))>0)
160 {
161 e.push_back(index);
162 s.push_back(edge[index].v);
163 //cout<<"push "<<edge[index].v<<endl;
164 }
165 else
166 {
167 e.pop_back();
168 s.pop_back();
169 level[u]=maxdata;
170 }
171 }
172 else
173 {
174 cf=maxdata;
175 for(it=e.begin();it!=e.end();it++)
176 {
177 index=*it;
178 if(edge[index].w<cf)
179 cf=edge[index].w;
180 }
181 //cout<<"cf "<<cf<<endl;
182 sum+=cf;
183 last=-1;
184 for(it=e.begin();it!=e.end();it++)
185 {
186 index=*it;
187 edge[index].w-=cf;
188 edge[edge[index].rnum].w+=cf;
189 if(last==-1 && edge[index].w==0)
190 last=edge[index].u;
191 }
192 while(s.back()!=last)
193 {
194 e.pop_back();
195 s.pop_back();
196 }
197 }
198 }
199 }
200 return sum;
201 }
202
203 int main()
204 {
205 Init();
206 printf("%d\n",Dinic());
207 return 0;
208 }