HDU - 3488 Tour(二分图最小权匹配+KM)
生活随笔
收集整理的這篇文章主要介紹了
HDU - 3488 Tour(二分图最小权匹配+KM)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出n個城市,再給出m條有向的道路,問若想以一個或多個環的形式遍歷所有的城市一次,所需要的最小權值是多少
題目分析:剛拿到這個題目是有點懵的,因為不知道題目讓求什么,其實轉換一下就豁然開朗了,首先是遍歷一次和每個城市都要經過一次(除了每個環起點和終點的城市可以經過兩次),我們可以將n個城市抽象為一個二分圖,兩個子集分別是每個點的入度點和出度點,這樣當n個入度點和n個出度點完備匹配后,就至少能形成一個環了
這里從網上拿大佬的一個圖來理解一下吧:
上圖中點1和點2可以成環,點3點4和點5也可以成環,就不用多說了吧
因為讓求路徑之和最小,也就是最小權匹配,而且還是完備匹配,所以直接掛KM模板就好了,記得讓權值取負,這個題目是有重邊和零邊的,注意處理一下就好了,小細節
代碼:
#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=210;int n,m;int la[N],lb[N];//頂標bool visa[N],visb[N];//訪問標記int maze[N][N];//邊權int match[N];//右部點匹配了哪一個左部點int upd[N];bool dfs(int x) {visa[x]=true;//訪問標記:x在交錯樹中for(int i=1;i<=n;i++){if(!visb[i]){if(la[x]+lb[i]-maze[x][i]==0)//相等子圖{visb[i]=true;//訪問標記:y在交錯樹中if(!match[i]||dfs(match[i])){match[i]=x;return true;}}elseupd[i]=min(upd[i],la[x]+lb[i]-maze[x][i]);}}return false; } int KM() {memset(match,0,sizeof(match));for(int i=1;i<=n;i++){la[i]=-inf;lb[i]=0;for(int j=1;j<=n;j++)la[i]=max(la[i],maze[i][j]);}for(int i=1;i<=n;i++){while(1)//直到左部點找到匹配{memset(visa,false,sizeof(visa));memset(visb,false,sizeof(visb));memset(upd,inf,sizeof(upd));if(dfs(i))break;int delta=inf;for(int j=1;j<=n;j++)if(!visb[j])delta=min(delta,upd[j]);for(int j=1;j<=n;j++)//修改頂標{if(visa[j])la[j]-=delta;if(visb[j])lb[j]+=delta;}}}int ans=0;for(int i=1;i<=n;i++)ans+=maze[match[i]][i];return ans; }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int w;cin>>w;while(w--){memset(maze,-inf,sizeof(maze));scanf("%d%d",&n,&m);while(m--){int u,v,w;scanf("%d%d%d",&u,&v,&w);maze[u][v]=max(-w,maze[u][v]);}printf("%d\n",-KM());}return 0; }?
總結
以上是生活随笔為你收集整理的HDU - 3488 Tour(二分图最小权匹配+KM)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ - 2112 Optimal M
- 下一篇: CodeForces - 1198A M