博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SGU 252 Railway Communication(KM)
阅读量:5887 次
发布时间:2019-06-19

本文共 2848 字,大约阅读时间需要 9 分钟。

题目链接:

题意:一个有向图。选择最少的路径覆盖所有点。在路径最少的情况下,使得所有路径经过的边的权值之和最小。

思路:没有权值的话就是一个最小路径覆盖。将每个点拆成两个点放在左右两个集合里,求最大匹配。然后怎么构造出最小路径呢?从右边没有被匹配的点开始沿着自己的匹配向下同时将与自己有边的删掉,度数为0时入栈。现在有了权值,还是求最小权值。KM可以求最大权。这时将每条边用INF-原来的权值代替。再跑KM。最后得到的路径就是最小权值的路径。

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))#define abs(x) ((x)>=0?(x):-(x))#define i64 long long#define u32 unsigned int#define u64 unsigned long long#define clr(x,y) memset(x,y,sizeof(x))#define CLR(x) x.clear()#define ph(x) push(x)#define pb(x) push_back(x)#define Len(x) x.length()#define SZ(x) x.size()#define PI acos(-1.0)#define sqr(x) ((x)*(x))#define FOR0(i,x) for(i=0;i
=0;i--)#define DOW1(i,x) for(i=x;i>=1;i--)#define DOW(i,a,b) for(i=a;i>=b;i--)using namespace std;void RD(int &x){scanf("%d",&x);}void RD(i64 &x){scanf("%I64d",&x);}void RD(u32 &x){scanf("%u",&x);}void RD(double &x){scanf("%lf",&x);}void RD(int &x,int &y){scanf("%d%d",&x,&y);}void RD(i64 &x,i64 &y){scanf("%I64d%I64d",&x,&y);}void RD(u32 &x,u32 &y){scanf("%u%u",&x,&y);}void RD(double &x,double &y){scanf("%lf%lf",&x,&y);}void RD(int &x,int &y,int &z){scanf("%d%d%d",&x,&y,&z);}void RD(i64 &x,i64 &y,i64 &z){scanf("%I64d%I64d%I64d",&x,&y,&z);}void RD(u32 &x,u32 &y,u32 &z){scanf("%u%u%u",&x,&y,&z);}void RD(double &x,double &y,double &z){scanf("%lf%lf%lf",&x,&y,&z);}void RD(char &x){x=getchar();}void RD(char *s){scanf("%s",s);}void RD(string &s){cin>>s;}void PR(int x) {printf("%d\n",x);}void PR(i64 x) {printf("%I64d\n",x);}void PR(u32 x) {printf("%u\n",x);}void PR(u64 x) {printf("%llu\n",x);}void PR(double x) {printf("%.4lf\n",x);}void PR(char x) {printf("%c\n",x);}void PR(char *x) {printf("%s\n",x);}void PR(string x) {cout<
<
> ans;stack
st;int find(int u){ fx[u]=1; int v; for(v=1;v<=n;v++) if(!fy[v]&&g[u][v]==Lx[u]+Ly[v]) { fy[v]=1; if(match[v]==-1||find(match[v])) { match[v]=u; return 1; } } return 0;}void DFS(int u,vector
&path){ int v; for(v=1;v<=n;v++) { if(p[u]!=v&&g[u][v]>0&&--d[v]==0) { st.push(v); } } d[u]=-1; path.pb(u); if(g[u][p[u]]==0) return; sum+=INF-g[u][p[u]]; DFS(p[u],path);}int main(){ RD(n,m); int i,j,u,v,c; FOR1(i,m) { RD(u,v,c); g[u][v]=INF-c; Lx[u]=max(Lx[u],g[u][v]); d[v]++; } clr(match,-1); FOR1(u,n) { while(1) { clr(fx,0); clr(fy,0); if(find(u)) break; c=INF; FOR1(i,n) if(fx[i]) FOR1(j,n) if(!fy[j]) { c=min(c,Lx[i]+Ly[j]-g[i][j]); } FOR1(i,n) { if(fx[i]) Lx[i]-=c; if(fy[i]) Ly[i]+=c; } } } FOR1(i,n) p[match[i]]=i; FOR1(i,n) if(!d[i]) st.push(i); vector
path; while(!st.empty()) { u=st.top(); st.pop(); path.clear(); DFS(u,path); ans.pb(path); } printf("%d %d\n",SZ(ans),sum); FOR0(i,SZ(ans)) { printf("%d",SZ(ans[i])); FOR0(j,SZ(ans[i])) printf(" %d",ans[i][j]); puts(""); } return 0;}

  

 

转载地址:http://lcgix.baihongyu.com/

你可能感兴趣的文章
luogu P1387 最大正方形
查看>>
Android图片圆角效果
查看>>
MSSQL跨服务器数据库查询
查看>>
WeChat Official Account Admin Platform API Introduction
查看>>
C语言写单链表的创建、释放、追加(即总是在最后的位置增加节点)
查看>>
poj1635
查看>>
C# LINQ详解(一)
查看>>
视频直播点播nginx-rtmp开发手册中文版
查看>>
iphone 添加CFNetwork.framework时,报错 socket
查看>>
ruby学习总结04
查看>>
Binary Tree Paths
查看>>
RESTful 架构详解(转)
查看>>
Ueditor自定义ftp上传
查看>>
线程以及多线程
查看>>
PHP队列的实现
查看>>
单点登录加验证码例子
查看>>
[T-SQL]从变量与数据类型说起
查看>>
稀疏自动编码之反向传播算法(BP)
查看>>
二叉搜索树转换成双向链表
查看>>
会员数据化运营
查看>>