最小路徑覆蓋邊 且輸出路徑 允許重複走遍

2021-08-28 16:10:46 字數 2036 閱讀 8663

給你一幅有向圖,你每次可以從任意點出發。圖中的每條邊至少要經過一次,問你至少要走幾次。

建圖:設每個點i的入度減去出度為d[i], s為源點,t為匯點。

對於d[i] > 0的點i, 連邊

對於d[i] < 0的點i, 連邊

其它邊連法與輸入的邊相同。

問題:對於輸入的每條邊下界為1,我們要求的是最小值,所以問題可以轉化為求該圖的最小流,

顯然,對於沒有下界的網路 其最小流就為零, 但該題的圖有下界,那麼如何求有下界的網路的最小流呢?

只有下界的最小流的解法:

先判斷該網路是否存在可行流,對於本題,顯然存在可行流。

如果可行流存在(假設可行流的值為f1),則從可行流出發,倒向求解。

即保持網路中的弧方向不變,將t作為源點,s作為匯點,反向流一次最大流後(假設求出的最大流為f2),

那麼原圖的最小流為f1 - f2。

#include #include #include #include using namespace std;

const int maxn = 110;

const int inf = 1e9;

#define pb push_back

#define mp make_pair

#define pii pair #define x first

#define y second

struct edge

edge(int v, int c, int next) : v(v), c(c), next(next) {}

} edge[maxn * maxn << 1];

int head[maxn], e;

int n, m;

int s, t;

void init()

void add(int s, int t, int c)

int d[maxn];

vectoredges[maxn];

int gap[maxn], dis[maxn], pre[maxn], cur[maxn];

int sap(int s, int t, int n)

gap[0] = n;

int u = pre[s] = s, aug = inf, maxf = 0, v;

while (dis[s] < n)

maxf += aug;

aug = inf;

}goto loop;

}} int d = n;

for (i = head[u]; ~i; i = edge[i].next)

} if (!(--gap[dis[u]]))

break;

++gap[dis[u] = d + 1];

u = pre[u];

} return maxf;

}bool flag;

int res[maxn], t;

int ans, cnt;

void dfs(int u)

if (!g) d[u]--, flag = 1;

}int main()

} s = n; t = n + 1;

for (i = 0; i < n; i++)

if (d[i] < 0)

add(i, t, -d[i]), ans -= d[i];

else if (d[i] > 0)

add(s, i, d[i]);

ans -= sap(s, t, t + 1);

printf("%d\n", ans);

for (i = 0; i < n; i++)

edges[i].clear();

for (i = 0; i < n; i++)

for (j = head[i]; ~j; j = edge[j].next)

if (!(j & 1))

for (i = 0; i < n; i++)

while (d[i] < 0)

}} return 0;

}

最小路徑覆蓋問題(最小路徑覆蓋)

本題題目描述可以發現很明顯的最小路徑覆蓋問題,又因為最小路徑覆蓋 節點數 二分圖最大匹配數,所以本題可以用匈牙利演算法求出二分圖最大匹配數,也可以向第一題那樣用網路流模型求出最大匹配數。本題建模時不同在於,每個點要分成兩個點,乙個為起點,乙個為終點,再來求二分圖最大匹配。然後麻煩就在於本題也要輸出路...

最小路徑覆蓋

zoj 2521 led display 題意 七段數碼顯示器,乙個數碼上的7段燈可以選擇滅掉一些後重複使用這個數碼,但滅掉的段不能再亮了。比如 6 可以 滅掉左小角的一段變成 5 來使用。但自己不能重複使用,即最少滅一段才能再次使用。現在按次序給出 乙個要現實的數碼序列,求需要的最少的燈數,使得能...

最小路徑覆蓋

差不多是模板題了 分析 最小路徑覆蓋 n 最大匹配數 n為 總點數 因為匹配的點 相互 交叉形成一條條最長路徑 剩餘沒匹配的點需要進行就是需要匹配數 及 最小路徑覆蓋數 include using namespace std define maxn 1005 int match maxn int v...