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 }

 

转载于:https://www.cnblogs.com/pushing-my-way/archive/2012/08/14/2637801.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值