最近一直想搞定這道題目。看了discuss才知道是網路流的題目,好多人說可以用二分圖匹配做,這個還沒想明白,還是看看經典的網路流吧。以前學習過相關的知識,但是由於學習的時間比較久,加上當時也是學的馬馬虎虎,所以導致現在對網路流完全不理解。這段時間,抽時間看了一些網上的資料,加上演算法導論上的一些解釋,也算整明白了。不敢獨享,在這裡曬曬自己學到的東西,分享。。。
偽**表示:
下面是偽**的具體**:
// max net stream
#include #include #include #include #include #include using namespace std;
mapmp;
vectorg[800];//無向圖
int n, m, k;
int que[800];
int d[800];
int stack[800];
int g[800][800];//有向流網路
bool v[800];
//尋找增廣層次路徑
bool bfs(int s, int t)
que[r ++ ] = u;
}} }
return false;
}int dinic_maxflow(int s, int t)
}ans += minn;//增加流量
for (i = 1; i < top; ++ i)//更新增廣路
while (top > base && stack[top - 1] != nminc)//重新回到標號點,一次標號,多次增廣
}else//找到增廣路
}if (i == g[p].size())
}} }
return ans;
}int main()
scanf("%d", &m);
tot = m;
//裝置和源點連線
while (m --)
g[0].push_back(mp[ss]);
g[mp[ss]].push_back(mp[str]);
g[mp[str]].push_back(mp[ss]);
g[mp[ss]][mp[str]] = 1;
} scanf("%d", &k);
//轉接點
while (k --)
g[mp[ss]].push_back(mp[str]);
g[mp[str]].push_back(mp[ss]);
g[mp[ss]][mp[str]] = 0xfffffff;
} printf("%d\n", tot - dinic_maxflow(0, 799));
} return 0;
}
1、為何找到一條增廣路徑中的最小值時,正向減去這個值,反向加上這個值。
在這幅圖中我們首先要增廣1->2->4->6,這時可以獲得乙個容量為2的流,但是如果不建立4->2反向弧的話,則無法進一步增廣,最終答案為2,顯然是不對的,然而如果建立了反向弧4->2,則第二次能進行1->3->4->2->5->6的增廣,最大流為3.
comzyh對反向弧的理解可以說是"偷梁換柱",請仔細閱讀:在上面的例子中,我們可以看出,最終結果是1->2->5->6和1->2->4->6和1->3->4->6.當增廣完1->2->4->5(代號a)後,在增廣1->3->4->2->5->6(代號b),相當於將經過節點2的a流從中截流1(總共是2)走2->5>6,而不走2->4>6了,同時b流也從節點4截流出1(總共是1)走4->6而不是4->2->5->6,相當於ab流做加法.
簡單的說反向弧為今後提供反悔的機會,讓前面不走這條路而走別的路.
2、為何找到一條以後,退到最小值那個點
不早了, gg, 睡覺。。。。。下次再細細學習。
我們一起來學習vue3
這是我學習vue3做的乙個demo,功能實現了增刪查改。是演示效果,沒有真正與資料庫打交道。做這個demo的過程中,我遇到了幾個問題。還好一一解決了。所以我覺得必要分享出來。給各位像我一樣的新手。少浪費一些時間,多學習一些新知識。先看看效果。整體效果,上面兩個導航按鈕,中間搜尋框,操作按鈕。下面是內...
時間程式設計 那些年我們一起學習linux程式設計
時間程式設計 時間型別 1 coordinated universal tine utc 世界標準時間 即 格林威治標準時間 greenwich mean time,gmt 2 calendar time 日曆時間,是用 從乙個標準時間點 如 1970年1 月1日0 點 到此時經過的秒數 來表示的時...
我們一起學網路 七) 網路層(路由選擇協議)
前面涉及到那麼多路由 分組的內容,現在終於到了正題,路由選擇協議 路由選擇協議的核心是路由演算法 路由選擇演算法可分為 靜態路由選擇策略 和 動態路由選擇策略 靜態路由選擇也叫 非自適應路由選擇 動態路由選擇也叫 自適應路由選擇 從名字就可以看出來,動態路由選擇比較複雜,但是能較好的適應各種網路情況...