码迷,mamicode.com
首页 > 其他好文 > 详细

3931: [CQOI2015]网络吞吐量【网络流】

时间:2015-04-10 22:01:32      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:

网络吞吐量
(network)
题目描述
路由是指通过计算机网络把信息从源地址传输到目的地址的活动,也是计算机网络设计中的重点和难点。网络中实现
路由转发的硬件设备称为路由器。为了使数据包最快的到达目的地,路由器需要选择最优的路径转发数据包。例如,
在常用的路由算法OSPF(开放式最短路径优先)中,路由器会使用经典的Dijkstra算法计算最短路径,然后尽量沿最短
路径转发数据包。
现在,若已知一个计算机网络中各路由器间的连接情况,以及各个路由器的最大吞吐量(即每秒能转发的数据包数
量),假设所有数据包一定沿最短路径转发,试计算从路由器1到路由器n的网络的最大吞吐量。计算中忽略转发及传
输的时间开销,不考虑链路的带宽限制,即认为数据包可以瞬间通过网络。路由器1到路由器n作为起点和终点,自身
的吞吐量不用考虑,网络上也不存在将1和n直接相连的链路。
输入格式
输入文件第一行包含两个空格分开的正整数n和m,分别表示路由器数量和链路的数量。网络中的路由器使用1到n编
号。
接下来m行,每行包含三个空格分开的正整数a、b和d,表示从路由器a到路由器b存在一条距离为d的双向链路。
接下来n行,每行包含一个正整数c,分别给出每一个路由器的吞吐量。
输出格式
输出一个整数,为题目所求吞吐量。
输入样例
7 10
1 2 2
1 5 2
2 4 1
2 3 3
3 7 1
4 5 4
4 3 1
4 6 1
5 6 2
6 7 1
1
100
20
50
20
60
1
输出样例
70

思路:首先跑最一遍短路,然后显然网络流上的边得是必须边嘛,然后限制是在点上的,因此需要拆点,跑一边maxflow即可

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 #define maxn 400009
  6 #define inf ((1LL<<63)-1)
  7 #define ll long long
  8 using namespace std;
  9 ll head[maxn],next[maxn],point[maxn],now,p[maxn],flow[maxn];
 10 ll n,m,value[maxn],dist[maxn],dis[maxn],x[maxn],y[maxn],v[maxn];
 11 void add(ll x,ll y,ll v)
 12 {
 13     next[++now]=head[x];
 14     head[x]=now;
 15     point[now]=y;
 16     value[now]=v;
 17 }
 18 void add2(ll x,ll y,ll v)
 19 {
 20     next[++now]=head[x];
 21     head[x]=now;
 22     point[now]=y;
 23     flow[now]=v;
 24     next[++now]=head[y];
 25     head[y]=now;
 26     point[now]=x;
 27     flow[now]=0;
 28 }
 29 void spfa(ll s)
 30 {
 31     memset(dist,-1,sizeof(dist));
 32     int visit[maxn]={0};
 33     visit[s]=1;
 34     queue<ll>q;
 35     q.push(s);
 36     dist[s]=0;
 37     while(!q.empty())
 38     {
 39         int u=q.front();
 40         q.pop();
 41         visit[u]=0;
 42         for(int i=head[u];i;i=next[i])
 43         {
 44             ll k=point[i];
 45             if(dist[k]==-1 || dist[u]+value[i]<dist[k])
 46             {
 47                 dist[k]=dist[u]+value[i];
 48                 p[k]=u;
 49                 if(!visit[k])
 50                 {
 51                     visit[k]=1;
 52                     q.push(k);
 53                 }
 54             }
 55         }
 56     }
 57 }
 58 int bfs(ll s,ll t)
 59 {
 60     queue<ll>q;
 61     memset(dis,-1,sizeof(dis));
 62     q.push(s);
 63     dis[s]=0;
 64     while(!q.empty())
 65     {
 66         ll u=q.front();
 67         q.pop();
 68         for(int i=head[u];i;i=next[i])
 69         {
 70             ll k=point[i];
 71             if(dis[k]==-1 && flow[i])
 72             {
 73                 dis[k]=dis[u]+1;
 74                 q.push(k);
 75             }
 76         }
 77     }
 78     return dis[t]!=-1;
 79 }
 80 ll dfs(ll s,ll d,ll t)
 81 {
 82     if(s==t)return d;
 83     ll res=0;
 84     for(int i=head[s];i&&res<d;i=next[i])
 85     {
 86         ll u=point[i];
 87         if(flow[i] && dis[u]==dis[s]+1)
 88         {
 89             ll dd=dfs(u,min(flow[i],d-res),t);
 90             if(dd)
 91             {
 92                 flow[i]-=dd;
 93                 flow[((i-1)^1)+1]+=dd;
 94                 res+=dd;
 95             }
 96         }
 97     }
 98     if(res==0)dis[s]=-1;
 99     return res;
100 }
101 int main()
102 {
103         scanf("%lld%lld",&n,&m);
104         for(int i=1;i<=m;i++)
105         {
106                 scanf("%lld%lld%lld",&x[i],&y[i],&v[i]);
107                 add(x[i],y[i],v[i]);
108                 add(y[i],x[i],v[i]);
109         }
110         spfa(1);
111         memset(head,0,sizeof(head));now=0;
112     for(int i=1;i<=m;i++)
113     {
114         if(dist[x[i]] + v[i] == dist[y[i]])
115         {
116             add2(x[i]+n,y[i],inf);
117         }
118         if(dist[y[i]] + v[i] == dist[x[i]])
119         {
120             add2(y[i]+n,x[i],inf);
121         }
122     }
123     ll b;
124         for(int i=1;i<=n;i++)
125     {
126         scanf("%lld",&b);
127         add2(i,i + n,(i==1||i==n)?inf:b);
128     }
129     ll ans=0;
130     while(bfs(1 ,n + n))
131     {
132         ans += dfs(1 ,inf ,n + n);
133     }
134     printf("%lld\n",ans);
135         return 0;
136 }

 

3931: [CQOI2015]网络吞吐量【网络流】

标签:

原文地址:http://www.cnblogs.com/philippica/p/4415638.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!