題意:n個星球,用最短的時間把k個超級計算機從s運到t;
其中,每個隧道是雙向的,乙個隧道裡面只能有乙個飛船在使用,乙個飛船上只有一台計算機。
分析:乙個隧道只能給乙個飛船用,那麼假設需要t天,那麼可以這樣建圖:
u結點,拆成t+1個,分別是 u0,u1,u2,...,ut;
u0是u的初始狀態,ui是u在第i天的狀態,那麼建圖就是:
a結點到b結點,ai 到 bi+1 一條容量為1的邊,bi 到 ai+1 的容量為1的一條邊。
對於每個結點,都有ui到ui+1 的容量是無窮大,因為可以停留。
一天一天增加結點,終點也發生變化,流量直到為k,就結束了。
然後輸出路徑:
遍歷原圖的上的每一條邊,注意edges是殘餘網路,idx+=2;這才加了一條邊。
問題問的路徑是(a,b)編號為a的飛機,到達行星 b,行星b就是有流量的那一條邊都後面那個結點。那麼,編號a怎麼求呢?
可以遍歷一下這k個飛機,如果 j 所在的位置location[j] = a[i] 的話,就ok了。
1 #include 23using
namespace
std;45
const
int maxn = 5000+10;6
const
int inf = 0x3f3f3f3f;7
8struct
edge;
1112
bool
operator
< (const edge& a,const edge&b)
1516
struct
dinic
2728
void clearnodes(int a,int
b) 32
33void addedge(int
from,int to,int
cap) );
35 edges.push_back((edge));
36 m =edges.size();
37 g[from].push_back(m-2
);38 g[to].push_back(m-1
);39}40
41bool
bfs() 56}
57}58return
vis[t];59}
6061
int dfs(int x,int
a) 73}74
return
flow;75}
7677
int maxflow(int s,int t,int
limit)
86return
flow;87}
88};
8990
dinic g;
9192
intmain()
93101
g.init();
102int day = 1
;103 g.clearnodes(0,n-1
);104
int flow = 0
;105
for(;;)
113 flow+=g.maxflow(s-1,day*n+t-1,k-flow);
114if(flow==k) break
;115 day++;
116}
117118 printf("
%d\n
",day);
119120
int idx = 0
;121 vectorlocation(k,s);
122123
for(int d=1;d<=day;d++)
135if(f1==0&&f2==1
) 139
}140
141 printf("%d"
,a.size());
142for(int i=0;i)
150}
151}
152 printf("\n"
);153
154}
155156
}157
158return0;
159 }
LA2957 網路流 藍書例題
分析 首先假設答案為t。構圖如下 把原圖的每個點u拆成t 1個,分別為u0,u1,其中u0是初始狀態的結點u,ui表示經過i天之後的結點u。對於原圖中的相鄰結點a和b,在新圖中新增一條從ai到bi 1的邊,容量為1,再新增一條bi到ai 1的邊,容量也為1。對於原圖中的每個結點u,新增 ui ui ...
Marriage Match IV 最大流 最短路
n 個點 m 條邊帶權有向圖,問每條邊最多只能走一次時從 s 到 t 的最短路徑數量。因為題目限制了每條邊最多只能走一次,所以不能直接用最短路來搞。但是我們可以轉化為網路流,所以可以設定邊的容量為 1。當然,首先需要找到在最短路上的邊,可以通過兩遍最短路求得,然後用這些邊跑 跑最小流肯定會tle 最...
LA11248 訓練指南 網路擴容 最大流
題意 給定乙個有向網路,每條邊均有乙個容量。問是否存在乙個從點1到點n,流量為c的流。如果不存在,是否可以恰好修改一條弧的容量,使得存在這樣的流?分析 先跑一遍最大流,如果最大流大於等於c,則輸possible。如果最大流小於c,則表明需要修改邊的流量。很顯然,需要修改的弧一定是滿流的弧。但是如果直...