[codeforces 508E]Maximum Matching
題目:Maximum Matching
傳送門:http://codeforces.com/contest/1038/problem/E
分析:
一個塊擁有{color1,val,color2},兩個塊相連要求相連處顏色相同,求價值最大的連接方案。
關心到color最大為4,以4種顏色為點,對于每個塊,在(color1,color2)間連一條邊權為(val)的邊,建一張4個點n條邊的圖。顯然,在圖上選一條價值最大的路徑(或回路)就是答案了。
方法一:
如果這張圖本身就是Eular路徑(或Eular回路),那就是答案了,不會有方案比全選更優。
如果本身不是Eular路徑(或Eular回路),我們可以刪掉一些邊,使其成為Eular路徑(或Eular環路)。
對于兩個點而言,最多刪去一條邊(若刪去兩條,這兩條構成的環可加入答案),刪去的邊一定是連接這兩個點的邊中權重最小的。
枚舉要刪掉的邊,對于4個點,兩兩連接,最多16條邊需要考慮是否刪除,枚舉刪掉邊的集合st(對該集合狀態壓縮),對去除該集合中的邊的集合求一條Eular路徑(或Eular回路)
復雜度:$O(2^16 * 4 * 4 * n)$ 實際上對存在自環的集合是不用考慮的,復雜度:$O(2^16 * n)$
引用:Ashishgup大佬的題解:http://codeforces.com/blog/entry/61692
方法二:
如果兩點(u,v)之間存在多條邊,每兩條邊就能走回本身,可從原圖中消去,在遍歷到u點或v點時加到答案中,注意不要重復加。
為了保證不破壞原圖的連通性,那最多只需保留2條邊,保留的當然是權值最小的邊啦(這些邊有可能不被選中,保留權值大的邊就可能得不到答案)
對4個點13條邊暴力DFS找一條路徑即可。這樣復雜度與n無關,題目的n可以進一步加強。
#include <bits/stdc++.h> int e[7][7][121],f[7][7],vis[7]; int ans=0; void dfs(int x,int tmp){for(int y=1;y<=4;++y)if(!vis[x] && !vis[y])tmp+=f[x][y];++vis[x];if(tmp>ans)ans=tmp;for(int y=1;y<=4;++y)if(x!=y && e[x][y][0]>0){tmp+=e[x][y][e[x][y][0]];--e[x][y][0];--e[y][x][0];dfs(y,tmp);++e[x][y][0];++e[y][x][0];tmp-=e[x][y][e[x][y][0]];}--vis[x];for(int y=1;y<=4;++y)if(!vis[x] && !vis[y])tmp-=f[x][y]; } int main(){//freopen("in.txt","r",stdin);int n;scanf("%d",&n);for(int i=0,u,val,v;i<n;++i){scanf("%d %d %d",&u,&val,&v);if(v>u)u^=v,v^=u,u^=v;e[v][u][++e[v][u][0]]=val;}for(int i=1;i<=4;++i){for(;e[i][i][0];--e[i][i][0])f[i][i]+=e[i][i][e[i][i][0]];for(int j=i+1;j<=4;++j){std::sort(e[i][j]+1,e[i][j]+e[i][j][0]+1);for(;e[i][j][0]>2;e[i][j][0]-=2)f[i][j]+=e[i][j][e[i][j][0]]+e[i][j][e[i][j][0]-1];e[j][i][0]=e[i][j][0];e[j][i][1]=e[i][j][1];e[j][i][2]=e[i][j][2];f[j][i]=f[i][j];}}dfs(4,0);for(int i=1;i<=4;++i)dfs(i,0);printf("%d",ans);return 0; }?
方法3:
我們可以設計一個復雜度與n相關的做法,這樣顏色數量可以加強。
定義f[i][j][x][y]:[i,j]區間里的鏈左右端點顏色為(x,y);
轉移方程:
1繼承:f[i][j][x][y]: max{f[i][k][x][y],f[k+1][j][x][y]};
2拼接:f[i][j][x][y]: max{f[i][k][x][t]+f[k+1][j][t][y],?f[k+1][j][x][t]+f[i][k][t][y]};
引用:http://codeforces.com/contest/1038/submission/42602607
方法4:
對于本題而言,在連通塊中,每當找到一個環就可以直接加入到答案中。最后可能會剩下一些零星的邊,對于只有4個點的圖而言的,只有剩下$e_{a,b},e_{c,d}$這種情況要考慮,刪除一條就好了,可以從加入答案的邊中用權值最小的邊替換剩下的邊,刪掉。等效于刪去一條最小邊。
找環(實際上不關心環的具體情況,與找Eular路徑(回路)方法相同,使用Fleury算法,復雜度O(n))
聯通塊可用并查集維護。
引用:http://codeforces.com/contest/1038/submission/42587804
?
轉載于:https://www.cnblogs.com/hjj1871984569/p/9646147.html
總結
以上是生活随笔為你收集整理的[codeforces 508E]Maximum Matching的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: div垂直水平居中经常使用的方法
- 下一篇: 搭建好看的静态博客(使用Hexo进行搭建