题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=252

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

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

#include <iostream>
#include <cstdio>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <map>#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<x;i++)
#define FOR1(i,x) for(i=1;i<=x;i++)
#define FOR(i,a,b) for(i=a;i<=b;i++)
#define DOW0(i,x) for(i=x;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<<x<<endl;}const int INF=100000000;
const int N=105;
int g[N][N],fx[N],fy[N],match[N],Lx[N],Ly[N];
int n,m,p[N],d[N],sum;
vector<vector<int> > ans;
stack<int> 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<int> &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<int> 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;
}

  

SGU 252 Railway Communication(KM)相关推荐

  1. 与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast)...

    原文:与众不同 windows phone (32) - Communication(通信)之任意源组播 ASM(Any Source Multicast) [索引页] [源码下载] 与众不同 win ...

  2. 与众不同 windows phone (29) - Communication(通信)之与 OData 服务通信

    原文:与众不同 windows phone (29) - Communication(通信)之与 OData 服务通信 [索引页] [源码下载] 与众不同 windows phone (29) - C ...

  3. hdu 3488(uva 1349)(KM)

    这道题是uva 1349 的简化版,那题没过,不知道为什么.我觉得那题就是多了一个先判断他最大匹配数是不是n,是的话,再找最优匹配. 回到这题,匹配问题,又是有向图,直接想到了拆点法.然后发现若每个点 ...

  4. RPI Serial Communication (一)

    这篇文章是给谁看的? 给那些有一定的51,PIC 等单片机基础的,并且对树莓派的通用输入输出(GPIO)数据传输有兴趣的菜鸟们(noobs!),比如我. 我能从这篇文章中学到嘛? 这篇文章是新手入门向 ...

  5. Android 常用的地球经纬度转换公里(km)计算工具类

    地球赤道上环绕地球一周走一圈共40075.04公里,而@一圈分成360°,而每1°(度)有60,每一度一秒在赤道上的长度计算如下: 40075.04km/360°=111.31955km 111.31 ...

  6. codevs 1028 花店橱窗布置 (KM)

    /*裸地KM*/ #include<iostream> #include<cstdio> #include<cstring> #define maxn 110 #d ...

  7. LeetCode 252. Meeting Rooms (会议室)$

    Given an array of meeting time intervals consisting of start and end times [[s1,e1],[s2,e2],...] (si ...

  8. 实战ELK(9) Elasticsearch地理位置

    实战ELK(9) Elasticsearch地理位置 地理坐标点(geo-point) 是指地球表面可以用经纬度描述的一个点.地理坐标点可以用来计算两个坐标位置间的距离,或者判断一个点是否在一个区域中 ...

  9. Elasticsearch对地理数据查询(一)

    翻译版本:https://es.xiaoleilu.com/310_Geopoints/00_Intro.html 官方原文:https://www.elastic.co/guide/en/elast ...

最新文章

  1. Hadoop集群的NameNode的备份
  2. 深入java虚拟机学习 -- 类的加载机制(续)
  3. 如何使用ATS提高应用的安全性
  4. Docker 入门(1)虚拟化和容器
  5. java 缓冲流_Java缓冲流的使用
  6. 由Unity發佈到Google Play (Android Market)的步驟
  7. 首套房贷款首付多少?
  8. 迅雷版本哪个好android,哪个是最好的螃蟹?适用于Android手机的迅雷体验的新版本...
  9. android Paddle 视频字幕识别TTS语音
  10. 数据库设计的阶段任务
  11. 网页在线视频播放大全
  12. 【调色台】达芬奇调色台系列
  13. php 射影定理,中考数学复习:射影定理所涉基本图形,弦切角概念,垂径定理...
  14. python实现QQ聊天自动化
  15. Potplayer播放器安装后总是遇到BUG
  16. 天地劫幽城再临服务器维护,天地劫幽城再临开服时间是什么时候_天地劫幽城再临开服时间一览_3DM手游...
  17. 最常用的地道的英语口语
  18. linux下wget通过代理下载(shadow-socks + privoxy)
  19. 等距图标导航栏(isometric icon Nav Bar)
  20. 2022 极术通讯-2021中国云数据中心考察报告发布,Arm服务器促进多元算力发展

热门文章

  1. 单变量微积分笔记8——最值问题和相关变率
  2. C# DataTable怎么合计字段
  3. LFS安装过程记录(1)-准备工作
  4. 合成谬误与公地悲剧(为何设置产品总监职位及核算名义成本)
  5. java.lang.Math类的API介绍
  6. Vue.js 循环语句
  7. 06-02 Jenkins job 机制
  8. python判断图片相似度_Python比较两个图片相似度的方法
  9. python水印_Python如何为图片添加水印
  10. 欲练JS,必先攻CSS——前端修行之路