HIT 2739 - The Chinese Postman Problem - [带权有向图上的中国邮路问题][最小费用最大流]
题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2739
Time limit : 1 sec Memory limit : 64 M
A Chinese postman is assigned to a small town in China to deliver letters. In this town, each street is oriented and connects exactly two junctions. The postman's task is to start at the post office and pass each street at least once to deliver letters. At last, he must return to the post office.
Can you help him to make sure whether there exist feasible routes for him and find the minimum distance from all the feasible routes.
Input
Input contains multiple test cases. The first line is an integer T, the number of test cases. Each case begins with two integers N, M, with 2 ≤ N ≤ 100, 1 ≤ M ≤ 2000, representing the number of junctions and the number of streets respectively.
Then M lines will follow, each denoting a street. A street is represented by three integers u, v, d, with 0 ≤ u, v < N, 0 < d ≤ 1000, meaning this street whose length is d connects the junction u and v and the postman can only travel from junction u to v. Junctions are numbered from 0 to N-1. Junction 0 is always the post office. Note that there may be more than one street connecting the same pair of junctions.
Output
Output one line for each test case. If there exist feasible routes for the postman, output the minimum distance. Otherwise, output -1.
Sample Input
3
2 1
0 1 3
4 4
0 1 1
1 2 2
2 3 3
3 0 4
4 7
0 1 1
1 2 2
2 3 3
3 0 4
1 3 5
3 1 2
1 3 2
Sample Output
-1
10
21
题意:
带权有向图上的中国邮路问题:
一名邮递员需要经过每条有向边至少一次,最后回到出发点;
一条边多次经过权值要累加,问最小总权值是多少。(2 <= N <= 100, 1 <= M <= 2000)
构图:
首先是比较理论的部分:


因而有:
(优先判断:若原图的基图不连通,或者存在某个点的入度或出度为 0 则无解,then可以直接跳到下一个test case;)
统计所有点的 D[i] = outdegree[i] - indegree[i];
对于 D[i] < 0 的点,加边(s, i, Di, 0);对于 D[i] > 0 的点,加边(i, t, -Di, 0);
(判断:若所有D[i]全为0,直接输出sum = Σ( all D[i][j] ) ,其中 D[i][j] 为边(i, j)的权值,then可以直接跳到下一个test case;)
对原图中的每条边(i, j),在网络中加边(i, j, ∞, D[i][j]);
求一次最小费用最大流,费用加上原图所有边权和即为结果。
代码:
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define MAXN 105
#define MAXM 2*(2005+2*MAXN)
#define INF 0x3f3f3f3f
using namespace std;
int n,m;
struct Edge{
int u,v,c,f,a;
};
struct MCMF
{
int s,t,ne;
Edge E[MAXM];
int head[MAXN],next[MAXM];
int vis[MAXN];
int d[MAXN];
int pre[MAXN];
int aug[MAXN];
void init()
{
ne=;
memset(head,-,sizeof(head));
}
void addedge(int from,int to,int cap,int cost)
{
E[ne].u=from, E[ne].v=to, E[ne].c=cap, E[ne].f=, E[ne].a=cost;
next[ne]=head[from]; head[from]=ne++;
E[ne].u=to, E[ne].v=from, E[ne].c=, E[ne].f=, E[ne].a=-cost;
next[ne]=head[to]; head[to]=ne++;
}
bool SPFA(int s,int t,int &flow,int &cost)
{
memset(d,INF,sizeof(d));
memset(vis,,sizeof(vis));
d[s]=, vis[s]=, pre[s]=, aug[s]=INF;
queue<int> q;
q.push(s);
while(!q.empty())
{
int now=q.front(); q.pop();
vis[now]=;
for(int i=head[now];i!=-;i=next[i])
{
Edge& e=E[i];
int nex=e.v;
if(e.c>e.f && d[nex]>d[now]+e.a)
{
d[nex]=d[now]+e.a;
pre[nex]=i;
aug[nex]=min(aug[now],e.c-e.f);
if(!vis[nex])
{
q.push(nex);
vis[nex]=;
}
}
}
}
if(d[t]==INF) return ;
flow+=aug[t];
cost+=d[t]*aug[t];
for(int i=t;i!=s;i=E[pre[i]].u)
{
E[pre[i]].f+=aug[t];
E[pre[i]^].f-=aug[t];
}
return ;
}
int mincost()
{
int flow=,cost=,cnt=;
while(SPFA(s,t,flow,cost));
return cost;
}
}mcmf; int outd[MAXN],ind[MAXN],sum;
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d\n",&n,&m); memset(outd,,sizeof(outd));
memset(ind,,sizeof(ind));
mcmf.s=, mcmf.t=n+; mcmf.init();
sum=; for(int i=,u,v,d;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&d);
u++, v++, sum+=d;
mcmf.addedge(u,v,INF,d);
outd[u]++;
ind[v]++;
} bool hasAns=,all_d_is_zero=;
for(int i=,d;i<=n;i++)
{
if(outd[i]== || ind[i]==)//显然不能有欧拉回路
{
hasAns=;
break;
}
d=outd[i]-ind[i];
if(d!=) all_d_is_zero=;
if(d>) mcmf.addedge(i,mcmf.t,d,);
if(d<) mcmf.addedge(mcmf.s,i,-d,);
}
if(!hasAns)
{
printf("-1\n");
continue;
}
if(all_d_is_zero)
{
printf("%d\n",sum);
continue;
} printf("%d\n",mcmf.mincost()+sum);
}
}
(之前2713用STL超时,搞得这题也不敢用STL,继续数组模拟邻接表,然后最大边数MAXM没开好,RE两次、TLE一次……)
HIT 2739 - The Chinese Postman Problem - [带权有向图上的中国邮路问题][最小费用最大流]的更多相关文章
- HITOJ 2739 The Chinese Postman Problem(欧拉回路+最小费用流)
The Chinese Postman Problem My Tags (Edit) Source : bin3 Time limit : 1 sec Memory limit : 6 ...
- Chinese Postman Problem Aizu - DPL_2_B(无向图中国邮路问题)
题意: 带权无向图上的中国邮路问题:一名邮递员需要经过每条边至少一次,最后回到出发点,一条边多次经过权值要累加,问最小总权值是多少.(2 <= N <= 15, 1 <= M < ...
- [C++]多源最短路径(带权有向图):【Floyd算法(动态规划法)】 VS n*Dijkstra算法(贪心算法)
1 Floyd算法 1.1 解决问题/提出背景 多源最短路径(带权有向图中,求每一对顶点之间的最短路径) 方案一:弗洛伊德(Floyd算法)算法 算法思想:动态规划法 时间复杂度:O(n^3) 形式上 ...
- [算法] Dijkstra算法(带权有向图 最短路径算法)
一.带权有向图 二.算法原理 1)由于我们的节点是从1-6,所以我们创建的列表或数组都是n+1的长度,index=0的部分不使用,循环范围为1-6(方便计算). 2)循环之前,我们先初始化dis数组和 ...
- HDU - 6437 Problem L.Videos 2018 Multi-University Training Contest 10 (最小费用最大流)
题意:M个影片,其属性有开始时间S,结束时间T,类型op和权值val.有K个人,每个人可以看若干个时间不相交的影片,其获得的收益是这个影片的权值val,但如果观看的影片相邻为相同的属性,那么收益要减少 ...
- hdu 1853 Cyclic Tour (二分匹配KM最小权值 或 最小费用最大流)
Cyclic Tour Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/65535 K (Java/Others)Total ...
- The Chinese Postman Problem HIT - 2739(有向图中国邮路问题)
无向图的问题,如果每个点的度数为偶数,则就是欧拉回路,而对于一个点只有两种情况,奇数和偶数,那么就把都为奇数的一对点 连一条 边权为原图中这两点最短路的值 的边 是不是就好了 无向图中国邮路问 ...
- D. The Door Problem 带权并查集
http://codeforces.com/contest/776/problem/D 注意到每扇门都有两个东西和它连接着,那么,如果第i扇门的状态是1,也就是已经打开了,那么连接它的两个按钮的状态应 ...
- HIT 2715 - Matrix3 - [最小费用最大流][数组模拟邻接表MCMF模板]
题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=2715 Time limit : 5 sec Memory limit : 64 M Zhouguyue ...
随机推荐
- c#POST请求php接口
POST请求php接口 /// <summary> /// 指定Post地址使用Get 方式获取全部字符串 /// </summary> /// <param name= ...
- it码农之心灵鸡汤(一)
到底该怎么面对工作,到底怎么面临人生.到底怎么面临青春,对于打工的人来说这些一直都是心中一直无法解惑的谜团. 对于人们怎样看待工作,以前华为创始人任正非说过:非常多人问我,来公司工作有没有双休?需不须 ...
- RPM常用命令解释
RPM软件包管理器,英文:RPM Package Manager(原Red Hat Package Manager,现在是一个递归缩写) -i安装rpm包 -u升级rpm包 -q查询已安装的软件信息 ...
- Window日志分析
0X00 简介 0x01 基本设置 A.Windows审核策略设置 前提:开启审核策略,若日后系统出现故障.安全事故则可以查看系统的日志文件,排除故障,追查入侵者的信息等. 打开设置窗口 Window ...
- Libjingle库 综述
国内现在很多语音聊天工具都是基于TURN方式实现的,包括YY.AK等等,这种方式对于服务器的性能要求很高,而且在用户量增大的时候,服务器压力也会越来越大,用户的语音质量也会受到很大影响.而基于P2P方 ...
- Four Ways to Create a Thread
Blaise Pascal Magazine Rerun #5: Four Ways to Create a Thread This article was originally written ...
- linux下c语言获取当前时间
和时间有关的函数定义在头文件”time.h”中 常用函数: time_t time(time_t *t); 函数说明:此函数会返回从公元 1970 年1 月1 日的UTC 时间从0 时0 分0 秒算起 ...
- N76E003系统时钟
系统时钟源N76E003共有3种系统时钟源,包括: 内部高速/低速振荡器.外部输入时钟.它们每一个都可以作为N76E003的系统时钟源.开启不同的时钟源可能会影响到多功能引脚P3.0/XIN .内部振 ...
- 【Python3】 使用django 2.0 + python3.6.4 创建应用
python版本:3.6.4 django版本:2.0 1 创建应用 输入命令 python manage.py startapp blog 2 在项目目录创建 templates文件夹 用于存放我们 ...
- PowerDesigner 同名问题解决 Entity Attribute name uniqueness
选择"Tools -> Model Options"后 "Allow reuse"复选框,建议把这个钩也去掉 Tool->check model.. ...