題目大意:
給出乙個v(3≤v≤1000)個點e(3≤e≤10000)條邊的有向加權圖,求1~v的兩條不相交(除了起點和終點外沒有公共點)的路徑,使得權和最小。如圖11-15所示,從1到6的兩條最優路徑為1-3-6(權和為33)和1-2-5-4-6(權和為53)。--------摘自《劉汝佳演算法競賽入門經典》
方法:將每乙個點拆成2個點(除去1,n),連線一條權值為0,流量為1的邊,1和n拆成的兩個點之間的流量限制為2,將每條邊的流量設定為1,這樣跑一遍最小費用最大流,即可得到
兩條不相交的路徑,且權值最小。
**:
#include #include#include
#include
#include
#include
#include
#include
#define maxn 2000+10
#define maxm 30000+100
#define inf 0x3f3f3f3f
using
namespace
std;
typedef
long
long
ll;struct
edge
;edge edge[maxm];
inthead[maxn], edgenum;
int pre[maxn];//
記錄增廣路徑上 到達點i的邊的編號
ll dist[maxn];
bool
vis[maxn];
int n, m;//
點數 邊數
int source, sink;//
超級源點 超級匯點
void
init()
void addedge(int u, int v, int w, intc);
edge[edgenum] =e1;
head[u] = edgenum++;
edge e2 = ;
edge[edgenum] =e2;
head[v] = edgenum++;
}bool spfa(int s, int t)//
尋找花銷最少的路徑}}
}return pre[t] != -1;//
可達返回true
}void mcmf(int s, int t, ll &cost, int &flow)
//增廣
for(int i = pre[t]; i != -1; i = pre[edge[i^1
].to])
flow += min;//
總流量累加}}
void getmap(int n,int
m) addedge(
1,1+n,2,0
); addedge(n,n+n,2,0
);
intp,q,r;
for (int i=1;i<=m;i++)
}int
main()
return0;
}
UVA 1658(網路流經典拆點方法)
把每個點 除了1,n 之外拆成i和i1,兩點間連一條容量為1,費用為零的邊,這樣可以限定,每個點只被跑到一次,那麼之後跑乙個最流量為2的最小費用流就可以了。至於其他邊,流量設為1,保證每個邊只被跑到一次。pragma comment linker,stack 1024000000,102400000...
UVa 1658 海軍上將(最小費用最大流)
題意 給出乙個v個點e條邊的有向加權圖,求1 v的兩條不相交 除了起點和終點外公共點 的路徑,使得權和最小。思路 把2到v 1的每個點拆分為兩個節點,容量為1,也就是只可以用一次,費用為0,然後求1到v的流量為2的最小費用流。1 include 2 include 3 include 4 inclu...
uva 1658 Admiral (最小費最大流)
題目大意 在圖中找出兩條沒有交集的線路,要求這兩條線路的費用最小。解題思路 還是拆點建圖的問題。首先每乙個點都要拆成兩個點。比如a點拆成a a 起點和終點的兩點間的容量為2費用為0,保證了僅僅找出兩條線路。其餘點的容量為1費用為0,保證每點僅僅走一遍,兩條線路無交集。然後依據題目給出的要求繼續建圖。...