zoj 2342 Roads
来源:互联网 发布:linux如何查看内核日志 编辑:程序博客网 时间:2024/06/06 11:45
在最优策略中,我们只会减少石头路的费用,增加烂泥路的费用,设这个改变量为
KM算法还是略神奇的,有待加强理解!
#include <bits/stdc++.h>using namespace std;const int maxn = 66;const int maxN = 410;int lx[maxN];int ly[maxN];int sx[maxN];int sy[maxN];int match[maxN];int weight[maxN][maxN];int sz;bool path(int u){ sx[u] = true; for(int v=1;v<=sz;v++){ if(!sy[v] && lx[u] + ly[v] == weight[u][v]){ sy[v] = true; if(match[v] == -1 || path(match[v])){ match[v] = u; return true; } } } return false;}int bestmatch(){ int i,j; for(i=1;i<=sz;i++){ lx[i] = 0x80000000; ly[i] = 0; for(j=1;j<=sz;j++){ if(lx[i]<weight[i][j]){ lx[i] = weight[i][j]; } } } memset(match,-1,sizeof(match)); for(int u=1;u<=sz;u++){ while(1){ memset(sx,0,sizeof(sx)); memset(sy,0,sizeof(sy)); if(path(u)){ break; } int dx = 0x7fffffff; for(i=1;i<=sz;i++){ if(sx[i]){ for(j=1;j<=sz;j++){ if(!sy[j]){ dx = min(lx[i]+ly[j]-weight[i][j],dx); } } } } for(i=1;i<=sz;i++){ if(sx[i]){ lx[i] -= dx; } if(sy[i]){ ly[i] += dx; } } } } int sum = 0; for(i=1;i<=sz;i++){ sum+=weight[match[i]][i]; } return sum;}vector<int> adj[maxn];int height[maxn];int p[maxn];int pEdge[maxn];struct Edge{ int u; int v; int w; Edge(int u,int v,int w):u(u),v(v),w(w){ } Edge(){ }}edges[maxN];void predfs(int u){ for(int i=0;i<adj[u].size();i++){ int v = edges[adj[u][i]].u; if(v==u){ v = edges[adj[u][i]].v; } if(v!=p[u]){ p[v] = u; pEdge[v] = adj[u][i]; height[v] = height[u] + 1; predfs(v); } }}void init(){ memset(weight,0,sizeof(weight)); memset(adj,0,sizeof(adj)); memset(p,0,sizeof(p));}void addedge(int u,int v,int id){ adj[u].push_back(id); adj[v].push_back(id);}int uu[maxN];int vv[maxN];int ww[maxN];int main(){ int t; cin>>t; while(t--){ init(); int n,m; cin>>n>>m; for(int i=1;i<=m;i++){ cin>>uu[i]>>vv[i]>>ww[i]; if(i<n){ edges[i] = Edge(uu[i],vv[i],ww[i]); addedge(uu[i],vv[i],i); }else{ } } predfs(1); int szX = n-1; int szY = m-n+1; sz = max(szX,szY); int Yid = 1; for(int i=n;i<=m;i++){ int u = uu[i]; int v = vv[i]; if(height[u]>height[v]){ swap(u,v); } int Xid; int sum; // move v while(height[v] > height[u]){ Xid = pEdge[v]; sum = ww[Xid] - ww[i]; if(sum<0){ sum = 0; } weight[Xid][Yid] = sum; v = p[v]; } //move u and v while(u!=v){ Xid = pEdge[u]; sum = ww[Xid] - ww[i]; if(sum<0){ sum = 0; } weight[Xid][Yid] = sum; Xid = pEdge[v]; sum = ww[Xid] - ww[i]; if(sum<0){ sum = 0; } weight[Xid][Yid] = sum; u = p[u]; v = p[v]; } Yid++; }/* for(int i=1;i<=sz;i++){ for(int j=1;j<=sz;j++){ cout<<weight[i][j]<<" "; } cout<<endl; }*/ bestmatch(); for(int i=1;i<=szX;i++){ cout<<ww[i] - lx[i]<<endl; } for(int i=1;i<=szY;i++){ cout<<ww[i+n-1] + ly[i]<<endl; } } return 0;}
0 0
- zoj 2342 Roads
- ZOJ 2342 Roads 二分图匹配
- zoj 1406 Jungle Roads
- ZOJ 1406.Jungle Roads
- zoj 1406 Jungle Roads
- zoj - 1406 - Jungle Roads
- ZOJ 1406 Jungle Roads
- zoj 1406 jungle roads
- zoj 2923 Calculate Roads
- ZOJ 1406 Jungle Roads (kruskal)
- ZOJ 1406 Jungle Roads 【kruskal】
- prim zoj 1406 Jungle Roads
- zoj 1406 Jungle Roads(Prim || Kruskal)
- ZOJ 1406 Jungle Roads (最小生成树)
- zoj 1406 Jungle Roads 最小生成树
- zoj 1406 Jungle Roads(简单-MST)
- ZOJ 1406 Jungle Roads (最小生成树)
- Jungle roads (zoj 1406 hdoj 1301)
- python 多线程 join 的 细节问题 注意使用事项
- Generate Parentheses 生成括号-- LintCode题解
- 机器学习矩阵求导
- NYOJ吝啬的国度(搜索)
- 悔往昔叹息,望前路迷惘却未惶。
- zoj 2342 Roads
- C - Heavy Transportation——HOJ
- web day20 单表练习之分页,java web监听器, 国际化
- u-boot.lds文件诠释
- 如何右键新建HTML
- 我理解的设计模式:单例模式
- 人工智能中对机器学非常简要的介绍
- 模板-KM算法
- Reverse Nodes in k-Group