Random Maze

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1669    Accepted Submission(s): 682

Problem Description
In the game “A Chinese Ghost Story”, there are many random mazes which have some characteristic:
1.There is only one entrance and one exit.
2.All the road in the maze are unidirectional.
3.For the entrance, its out-degree = its in-degree + 1.
4.For the exit, its in-degree = its out-degree + 1.
5.For other node except entrance and exit, its out-degree = its in-degree.

There is an directed graph, your task is removing some edge so that it becomes a random maze. For every edge in the graph, there are two values a and b, if you remove the edge, you should cost b, otherwise cost a.
Now, give you the information of the graph, your task if tell me the minimum cost should pay to make it becomes a random maze.

 
Input
The first line of the input file is a single integer T.
The rest of the test file contains T blocks. 
For each test case, there is a line with four integers, n, m, s and t, means that there are n nodes and m edges, s is the entrance's index, and t is the exit's index. Then m lines follow, each line consists of four integers, u, v, a and b, means that there is an edge from u to v. 
2<=n<=100, 1<=m<=2000, 1<=s, t<=n, s != t. 1<=u, v<=n. 1<=a, b<=100000
 
Output
For each case, if it is impossible to work out the random maze, just output the word “impossible”, otherwise output the minimum cost.(as shown in the sample output)
 
Sample Input
2
2 1 1 2
2 1 2 3
5 6 1 4
1 2 3 1
2 5 4 5
5 3 2 3
3 2 6 7
2 4 7 6
3 4 10 5
 
Sample Output
Case 1: impossible
Case 2: 27
 
Source
 
Recommend
lcy

解析:

  每条边由两种选择,删除还是不删除,这两者所用的权值都是正数,如果一正一负是不是就是最大权闭合子图

其实这题就和欧拉路的混合图建边一样 先定向建边 然后反悔

但这个不是 ,所以我们可以对一条边进行假设,如果边 u - > v 的 a < b 那么我们在原图中就保留这条边 sum += a,网络图中 建一条v - > u的反向边 权值为b - a  in[v]++, out[u]++ (这里统计的是原图中的度数) 如果求费用流时走了这条边就意味着 原图中不走这条边  也就是删除这条边,同理 b < a 但这一步不统计度数 因为这一步的边在原图中已经删除了

  然后in[s_]++, out[t_]++ 使得每个节点入度 = 出度

但实际却不是这样,通过这样构建图之后,原图中并不是所有的点的入度等于出度, 所以要通过网络图进行调整,

遍历每个点如果in[i] < out[i]  则从i 到 t 添加一条权值为out[i] - in[i]的边,注意这里in[i] out[i]是统计的原图中的度数,|out[i] - in[i]| 表示原图中出度和入度的差额 这里的权值为|out[i] - in[i]|, 而混合欧拉图中的权值为|out[i] - in[i]| / 2,知道为什么嘛。。。因为这里是删除边 而 混合欧拉图里是把边反向   嗯 是的 我和个傻子一样

#include <iostream>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <map>
#include <cctype>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <bitset>
#define rap(i, a, n) for(int i=a; i<=n; i++)
#define rep(i, a, n) for(int i=a; i<n; i++)
#define lap(i, a, n) for(int i=n; i>=a; i--)
#define lep(i, a, n) for(int i=n; i>a; i--)
#define rd(a) scanf("%d", &a)
#define rlld(a) scanf("%lld", &a)
#define rc(a) scanf("%c", &a)
#define rs(a) scanf("%s", a)
#define rb(a) scanf("%lf", &a)
#define rf(a) scanf("%f", &a)
#define pd(a) printf("%d\n", a)
#define plld(a) printf("%lld\n", a)
#define pc(a) printf("%c\n", a)
#define ps(a) printf("%s\n", a)
#define MOD 2018
#define LL long long
#define ULL unsigned long long
#define Pair pair<int, int>
#define mem(a, b) memset(a, b, sizeof(a))
#define _ ios_base::sync_with_stdio(0),cin.tie(0)
//freopen("1.txt", "r", stdin);
using namespace std;
const int maxn = , INF = 0x3f3f3f3f, LL_INF = 0x7fffffffffffffff;
int n, m, k, q, s, t;
int head[], d[], vis[], p[], f[], nex[maxn];
int in[], out[];
int flow, value, cnt;
struct node
{
int u, v, w, c;
}Node[maxn]; void add_(int u, int v, int w, int c)
{
Node[cnt].u = u;
Node[cnt].v = v;
Node[cnt].w = w;
Node[cnt].c = c;
nex[cnt] = head[u];
head[u] = cnt++;
} void add(int u, int v, int w, int c)
{
add_(u, v, w, c);
add_(v, u, -w, );
} int spfa()
{
deque<int> Q;
mem(vis, );
mem(p, -);
mem(d, INF);
d[s] = ;
Q.push_front(s);
vis[s] = ;
p[s] = , f[s] = INF;
while(!Q.empty())
{
int u = Q.front(); Q.pop_front();
vis[u] = ;
for(int i = head[u]; i != -; i = nex[i])
{
node e = Node[i];
if(d[e.v] > d[u] + Node[i].w && Node[i].c > )
{
d[e.v] = d[u] + Node[i].w;
p[e.v] = i;
f[e.v] = min(f[u], Node[i].c);
if(!vis[e.v])
{
if(Q.empty()) Q.push_front(e.v);
else
{
if(d[e.v] < d[Q.front()]) Q.push_front(e.v);
else Q.push_back(e.v);
}
vis[e.v] = ;
}
}
}
}
if(p[t] == -) return ;
flow += f[t]; value += f[t] * d[t];
for(int i = t; i != s; i = Node[p[i]].u)
{
Node[p[i]].c -= f[t];
Node[p[i] ^ ].c += f[t];
}
return ;
} void max_flow()
{
value = flow = ;
while(spfa());
} void init()
{
mem(head, -);
mem(in, );
mem(out, );
cnt = ;
} int main()
{
int T, kase = ;
rd(T);
while(T--)
{
init();
int u, v, a, b, s_, t_;
int sum = , sum_flow = ;
rd(n), rd(m), rd(s_), rd(t_);
s = , t = n + ;
rap(i, , m)
{
rd(u), rd(v), rd(a), rd(b);
if(a < b)
{
sum += a;
add(v, u, b - a, );
in[v]++, out[u]++;
}
else
{
sum += b;
add(u, v, a - b, );
// in[v]++, out[u]++;
}
}
// add(t_, s_, 0, 1);
in[s_]++, out[t_]++;
rap(i, , n)
{
cout << in[i] - out[i] << endl;
if(in[i] < out[i])
add(i, t, , (out[i] - in[i]));
else if (in[i] > out[i])
add(s, i, , (in[i] - out[i])), sum_flow += (in[i] - out[i]);
}
max_flow();
// cout << sum_flow << " " << flow << endl;
printf("Case %d: ", ++kase);
if(sum_flow != flow)
{
ps("impossible");
}
else
pd(sum + value); } return ;
}

Random Maze

Time Limit: 10000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1669    Accepted Submission(s): 682

Problem Description
In the game “A Chinese Ghost Story”, there are many random mazes which have some characteristic:
1.There is only one entrance and one exit.
2.All the road in the maze are unidirectional.
3.For the entrance, its out-degree = its in-degree + 1.
4.For the exit, its in-degree = its out-degree + 1.
5.For other node except entrance and exit, its out-degree = its in-degree.

There is an directed graph, your task is removing some edge so that it becomes a random maze. For every edge in the graph, there are two values a and b, if you remove the edge, you should cost b, otherwise cost a.
Now, give you the information of the graph, your task if tell me the minimum cost should pay to make it becomes a random maze.

 
Input
The first line of the input file is a single integer T.
The rest of the test file contains T blocks. 
For each test case, there is a line with four integers, n, m, s and t, means that there are n nodes and m edges, s is the entrance's index, and t is the exit's index. Then m lines follow, each line consists of four integers, u, v, a and b, means that there is an edge from u to v. 
2<=n<=100, 1<=m<=2000, 1<=s, t<=n, s != t. 1<=u, v<=n. 1<=a, b<=100000
 
Output
For each case, if it is impossible to work out the random maze, just output the word “impossible”, otherwise output the minimum cost.(as shown in the sample output)
 
Sample Input
2
2 1 1 2
2 1 2 3
5 6 1 4
1 2 3 1
2 5 4 5
5 3 2 3
3 2 6 7
2 4 7 6
3 4 10 5
 
Sample Output
Case 1: impossible
Case 2: 27
 
Source
 
Recommend
lcy

Random Maze HDU - 4067(预定义状态建边(贪心建边))的更多相关文章

  1. Paip.最佳实践-- Buildin variale 内建变量 ,魔术变量,预定义变量,系统常量,系统变量 1

    Paip.最佳实践-- Buildin variale 内建变量 ,魔术变量,预定义变量,系统常量,系统变量 1.1.1       C++内建变量(__LINE__).... 1.1.2       ...

  2. Atitit.预定义变量与变量预处理器

    Atitit.预定义变量与变量预处理器 1. 预定义变量与1 2. 变量预处理器1 3. 测试数据生成器3 1. 预定义变量与 姓名:$name 次数:$rdm 时间:$datetime 文件名:$f ...

  3. VS2013 预定义的宏

    Visual Studio 2013 预定义的宏 https://msdn.microsoft.com/zh-cn/library/b0084kay(v=vs.120).aspx 列出预定义的 ANS ...

  4. php预定义变量,超全局变量,魔术方法,特殊函数变量使用

    <?php /* * 本代码全部为测试函数代码,部分注释和写实例 * * 修改php.ini variables_order=”EGPCS” * 请注意$_REQUEST在优先级传参的时候会造成 ...

  5. C++ 中常见预定义宏的使用

    http://blog.csdn.net/hgl868/article/details/7058906 替代字符串: #define DOWNLOAD_IMAGE_LOG /var/log/png.l ...

  6. php的预定义数组

    PHP预定义变量数组 1.$_SERVER 变量由Web服务器设定或者直接与当前的脚本的执行环境相关联 $_SERVER超级全局变量包含由web服务器创建的信息,它提供了服务器和客户配置及当前请求环境 ...

  7. php预定义常量&变量

    PHP中可以使用预定义常量获取PHP中的信息,常用的预定义常量如下表所示. 常量名 功能  _FILE_ 默认常量,PHP程序文件名 _LINE_ 默认常量,PHP程序行数  PHP_VERSION ...

  8. 预定义变量 - PHP手册笔记

    预定义变量将所有的外部变量表示成内建环境变量,并且将错误信息表示成返回头.超全局变量是在全部作用域中始终可用的内置变量.在函数或方法中无需执行global $variable,就可以访问它们. $GO ...

  9. oracle预定义角色

    角色是相关权限的集合,使用角色能够简化权限的管理.简而言之就是oracle可以事先把一系列权限集中在一起(角色),打包赋予给用户,那么用户就具有了角色的一系列权限. oracle预定义角色有25种,它 ...

随机推荐

  1. 通过 Systemd Journal 收集日志

    随着 systemd 成了主流的 init 系统,systemd 的功能也在不断的增加,比如对系统日志的管理.Systemd 设计的日志系统好处多多,这里笔者就不再赘述了,本文笔者主要介绍 syste ...

  2. P2P平台介绍

    https://www.ludou.org/tutengdai.html https://www.tutengdai.com/register?invite_code=9991300

  3. 如何让.net程序支持TLS1.2

    1.将.Net FrameWork设置成4.6以上版本 2.在需要的类中引入命名空间 using System.Net; 3.在程序调用接口(如支付)的地方,加一段代码即可 System.Net.Se ...

  4. java的instanceof关键字

    java 中的instanceof 运算符是用来判断对象是否是 特定类或这个特定类的子类 的一个实例. 用法: result = object instanceof class 参数: Result: ...

  5. Python—包介绍

    包(Package) 当你的模块文件越来越多,就需要对模块文件进行划分,比如把负责跟数据库交互的都放一个文件夹,把与页面交互相关的放一个文件夹, . └── my_proj ├── crm #代码目录 ...

  6. B. School Marks(典型贪心)

    链接 [https://codeforces.com/contest/540/problem/B] 题意 某个人有n门成绩,k门已知,剩下的他可以个瞎改,但有个要求,最后分数和不超过x,且每门成绩不超 ...

  7. javaScript 删除本地cookie删不了

    一.js删除本地cookie无法删除 今天发现自己真的蠢爆了! 以下为cookie定义: 1.设置Cookie的key   2.设置Cookie的key-value值   3.过期时间-自定义(一般在 ...

  8. python_线程的开启、守护线程、锁、死锁、事件、定时器、条件、队列、池

    0.承上 什么是线程? CPU调度的最小单位. 线程是进程的必要组成单位. 主线程: 程序开始运行的时候,就产生了一个主线进程来运行这个程序. 子线程: 是由主线程开启的其他线程. · 各线程之间的工 ...

  9. js对字符串的一些操作方法

    1.charCodeAt(index); 返回一个整数,代表下标位置上字符的Unicode的编码. 2.fromCharCode(code1,code2,code3,...); code1代表Unic ...

  10. Linux 的相关操作

    切换权限   在linux环境下,用户之前的切换使用 “su - name,若要切换到root下面,则使用sudo su 命令即可. 在linux下安装软件,经常就是装完后不知道装到哪里去了 (201 ...