poj3469_dinic
题意:双核电脑上有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 }