分類: 圖論
uva && la
2013-07-21 16:48
112人閱讀收藏
舉報題意:
給你一幅有向圖,你每次可以從任意點出發。圖中的每條邊至少要經過一次,問你至少要走幾次。
建圖:
設每個點i的入度減去出度為d[i], s為源點,t為匯點。
對於d[i] > 0的點i, 連邊
對於d[i] < 0的點i, 連邊
其它邊連法與輸入的邊相同。
問題:
對於輸入的每條邊下界為1,我們要求的是最小值,所以問題可以轉化為求該圖的最小流,
顯然,對於沒有下界的網路 其最小流就為零, 但該題的圖有下界,那麼如何求有下界的網路的最小流呢?
只有下界的最小流的解法:
先判斷該網路是否存在可行流,對於本題,顯然存在可行流。
如果可行流存在(假設可行流的值為f1),則從可行流出發,倒向求解。
即保持網路中的弧方向不變,將t作為源點,s作為匯點,反向流一次最大流後(假設求出的最大流為f2),
那麼原圖的最小流為f1 - f2。
輸出路徑:
求完該圖的最小流以後,假如邊流了c流量,那麼說明邊需要走c+1次。
對於以上的情況,新建一幅要求路徑的圖。
你可以建c+1條邊, 也可以加一條邊和乙個資訊(訪問次數c+1)。
我用了後者的作法,但在理論上我們把它看成c+1條邊。
我們可以計算出這幅圖每個點的d[i](入度減去出度)。
這裡要注意有可能沒有邊可以走,那麼只能搜到乙個點,這種情況不用輸出也不用更新d[i]
每次搜到一條路就停止dfs,然後
輸出路徑。
**:
[cpp]view plain
copy
#include
#include
#include
#include
using
namespace
std;
const
intmaxn = 110;
const
intinf = 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];
inthead[maxn], e;
intn, m;
ints, t;
void
init()
void
add(
ints,
intt,
intc)
intd[maxn];
vectoredges[maxn];
intgap[maxn], dis[maxn], pre[maxn], cur[maxn];
intsap(
ints,
intt,
intn)
gap[0] = n;
intu = pre[s] = s, aug = inf, maxf = 0, v;
while
(dis[s] < n)
maxf += aug;
aug = inf;
} goto
loop;
} }
intd = 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;
intres[maxn], t;
intans, cnt;
void
dfs(
intu)
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;
}
乙隻有野心的小爬蟲
這個問題在程式設計師中的爭議很大,這裡不拉開情懷與逼格的爭議。對於大多數人,我的建議是 先暫時使用ide,這可以在學習的過程中讓你的精力主要集中在 的編寫上,對於執行和除錯也非常方便。但是你至少應該會一點vim的基礎操作,這樣可以方便你在伺服器部署 ctrl space 基本的 完成 類 方法 屬性...
做乙隻有追求的猿
昨天早上懷著忐忑的心情去面試 在中關村站下車時 空氣的濕度好像變的綿密了 果然 海淀居然在下雨?那好 去便利店買雨傘吧 結果可好 一堆人把雨傘搶光了 只有兩件雨衣了 沒辦法 硬著頭皮買雨衣吧 總不能淋感冒了不是 穿好雨衣的我看起來就是一外賣小哥 順著導航一路找過去發現不對 索性放棄不靠譜的導航直接找...
650 只有兩個鍵的鍵盤
最初在乙個記事本上只有乙個字元 a 你每次可以對這個記事本進行兩種操作 copy all 複製全部 你可以複製這個記事本中的所有字元 部分的複製是不允許的 paste 貼上 你可以貼上你上一次複製的字元。給定乙個數字n。你需要使用最少的操作次數,在記事本中列印出恰好n個 a 輸出能夠列印出n個 a ...