Kattis amazingadventures Amazing Adventures(费用流路径)题解
题意:
在一个\(100*100\)的方格中,要求从\(b\)走到\(g\),途中经过\(c\)但不经过\(u\),并且不能走已经做过的路。如果可以,就求出路径。
思路:
拆点建费用流,看能不能从\(c\)走两条路走到\(b,g\)。然后输出路径。
代码:
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<bitset>
#include<string>
#include<cstdio>
#include<vector>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 20000 + 5;
const int M = 50 + 5;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
const ll MOD = 1000000007;
struct Edge{
int to, next, cap, cost;
}edge[10000 * 4 * 10 + 100];
int head[maxn], tot;
int pre[maxn], dis[maxn];
bool vis[maxn];
int N;
void init(){
N = maxn;
tot = 0;
memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int cap, int cost){ //双向边
edge[tot].to = v;
edge[tot].cap = cap;
edge[tot].cost = cost;
edge[tot].next = head[u];
head[u] = tot++;
edge[tot].to = u;
edge[tot].cap = 0;
edge[tot].cost = -cost;
edge[tot].next = head[v];
head[v] = tot++;
}
bool spfa(int s, int t){
queue<int> q;
for(int i = 0; i <= N; i++){
dis[i] = INF;
vis[i] = false;
pre[i] = -1;
}
dis[s] = 0;
vis[s] = true;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
vis[u] = false;
for(int i = head[u];i != -1;i = edge[i].next){
int v = edge[i].to;
int c = edge[i].cap;
int w = edge[i].cost;
if(c && dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
pre[v] = i;
if(!vis[v]){
vis[v] = true;
q.push(v);
}
}
}
}
return pre[t] != -1;
}
int MCMF(int s, int t, int &cost){
int flow = 0;
cost = 0;
while(spfa(s, t)){
int MIN = INF;
for(int i = pre[t]; i != -1;i = pre[edge[i ^ 1].to]){
MIN = min(MIN, edge[i].cap);
}
for(int i = pre[t]; i != -1; i = pre[edge[i ^ 1]. to]){
edge[i]. cap -= MIN;
edge[i ^ 1]. cap += MIN;
cost += edge[i]. cost * MIN;
}
flow += MIN;
}
return flow;
}
int n, m ,bx, by, cx, cy, gx, gy, ux, uy;
int getid(int x, int y, int out){
return (x - 1) * m + y + n * m * out;
}
char getturn(int a, int b){
int x1 = (a - 1) / m + 1, x2 = (b - 1) / m + 1;
int y1 = a - (x1 - 1) * m, y2 = b - (x2 - 1) * m;
if(x1 + 1 == x2) return 'U';
if(x1 - 1 == x2) return 'D';
if(y1 + 1 == y2) return 'R';
if(y1 - 1 == y2) return 'L';
}
/***********************/
输出路径
string step;
int ans[20000], cnt;
vector<int> g[maxn];
void dfs(int s, int t){
vis[s] = 1;
if(s == t) return;
for(int i = 0; i < g[s].size(); i++){
int v = g[s][i];
if(!vis[v]){
vis[v] = 1;
ans[cnt++] = v;
dfs(v, t);
break;
}
}
}
void path(int st, int en){
for(int i = 1; i <= n * m; i++){
g[i].clear();
for(int j = head[i + n * m]; j != -1; j = edge[j].next){
int c = edge[j].cap;
int v = edge[j].to;
if(!c && i != v){ //流量为0
g[i].push_back(v);
}
}
}
string tmp;
memset(vis, 0, sizeof(vis));
step = "";
cnt = 0;
ans[cnt++] = getid(cx, cy, 0);
dfs(st, en), cnt--;
tmp = "";
if(ans[cnt - 1] == getid(gx, gy, 0)){
tmp = "";
for(int i = 0; i < cnt - 1; i++){
tmp += getturn(ans[i], ans[i + 1]);
}
step = step + tmp;
}
else{
tmp = "";
for(int i = cnt - 1; i > 0; i--){
tmp += getturn(ans[i], ans[i - 1]);
}
step = tmp + step;
}
cnt = 0;
ans[cnt++] = getid(cx, cy, 0);
dfs(st, en), cnt;
tmp = "";
if(ans[cnt - 1] == getid(gx, gy, 0)){
tmp = "";
for(int i = 0; i < cnt - 1; i++){
tmp += getturn(ans[i], ans[i + 1]);
}
step = step + tmp;
}
else{
tmp = "";
for(int i = cnt - 1; i > 0; i--){
tmp += getturn(ans[i], ans[i - 1]);
}
step = tmp + step;
}
}
/***********************/
int main(){
int cost;
int to[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
while(scanf("%d%d", &n, &m) && n + m){
init();
scanf("%d%d", &bx, &by);
scanf("%d%d", &cx, &cy);
scanf("%d%d", &gx, &gy);
scanf("%d%d", &ux, &uy);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
int x, y;
addEdge(getid(i, j, 0), getid(i, j, 1), 1, 1);
addEdge(getid(i, j, 1), getid(i, j, 0), 1, 1);
for(int k = 0; k < 4; k++){
x = i + to[k][0];
y = j + to[k][1];
if(x < 1 || y < 1 || x > n || y > m) continue;
if((x == ux && y == uy) || (i == ux && j == uy)) continue;
addEdge(getid(i, j, 1), getid(x, y, 0), 1, 1);
}
}
}
int st = getid(cx, cy, 1), en = 2 * n * m + 1;
addEdge(getid(bx, by, 1), en, 1, 1);
addEdge(getid(gx, gy, 1), en, 1, 1);
int flow = MCMF(st, en, cost);
if(flow < 2) printf("NO\n");
else{
path(getid(cx, cy, 0), en);
printf("YES\n");
cout << step << endl;
}
}
return 0;
}
Kattis amazingadventures Amazing Adventures(费用流路径)题解的更多相关文章
- 洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...
- 洛谷 P4016负载平衡问题【费用流】题解+AC代码
洛谷 P4016负载平衡问题 P4014 分配问题[费用流]题解+AC代码 负载平衡问题 题目描述 GG 公司有n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n ...
- POJ 3422 Kaka's Matrix Travels(拆点+最大费用流)题解
题意:小A从左上角走到右下角,每个格子都有一个价值,经过这个格子就把价值拿走,每次只能往下或往右走,问你走k次最多能拿多少价值的东西. 思路:这里有一个限制条件就是经过之后要把东西拿走,也就是每一格的 ...
- LightOJ 1071 Baker Vai(拆点+最大费用流)题解
题意:给一个n*m的方格,每个格子上都有一个数字表示价值,小A在左上角,他从左上角走到右下角只能向右或向下走,然后再从右下角走上左上角,这次只能向上或向左走,这两条路绝对没有重复,问你怎样走有最大价值 ...
- 【费用流】【CODEVS】1227 方格取数2
[算法]最小费用最大流(费用流) [题解] 费用流:http://www.cnblogs.com/onioncyc/p/6496532.html 本题构图: 在有限的k次行走中尽可能多的拿到数字,明显 ...
- 【网络流24题】No.21 (最长 k 可重区间集问题 最长不相交路径 最大费用流)
[] 输入文件示例input.txt4 21 76 87 109 13 输出文件示例output.txt15 [分析] 直接co题解好了,写得挺全.. [建模方法] 方法1 按左端点排序所有区间,把每 ...
- 网络费用流-最小k路径覆盖
多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- BZOJ.1927.[SDOI2010]星际竞速(无源汇上下界费用流SPFA /最小路径覆盖)
题目链接 上下界费用流: /* 每个点i恰好(最少+最多)经过一次->拆点(最多)+限制流量下界(i,i',[1,1],0)(最少) 然后无源汇可行流 不需要源汇. 注: SS只会连i',求SS ...
- 【洛谷2469/BZOJ1927】[SDOI2010]星际竞速(费用流/最小路径覆盖)
题目: 洛谷2469 分析: 把题目翻译成人话:给一个带边权的DAG,求一个路径覆盖方案使路径边权总和最小.从点\(i\)开始的路径需要额外加上\(A_i\)的权值. 回xian忆chang一xue下 ...
随机推荐
- 安装JDK与卸载JDK教程
卸载JDK 删除JDK的安装目录,也就是删除了主程序(通过环境变量可以找到) 删除java_home的环境变量 删除环境变量path中与java_home相关的 通过DOS命令cmd来检验是否卸载成功 ...
- 前端知识(二)01-NPM包管理器-谷粒学院
目录 一.简介 二.使用npm管理项目 1.项目初始化 2.修改npm镜像 3.npm install命令的使用 4.其它命令 一.简介 什么是NPM NPM全称Node Package Manage ...
- 前端知识(一)05 axios-谷粒学院
目录 一.axios的作用 二.axios实例 1.复制js资源 2.创建 axios.html 3.引入js 4.启动课程中心微服务 5.编写js 6.html渲染数据 7.跨域 8.使用生命周期函 ...
- uni-app开发经验分享十七: 开发微信公众号(H5)JSSDK 的使用方式
因为这个jssdk被uni-app坑了好多天,作者说支持1.4版本,但是我用1.4的两个分享的新方法一直不支持. 最后只能放弃了,期待什么时候能更新上. 基本的使用方法:第一步 - 下载使用方式下载地 ...
- STL_list容器
一.List简介 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的. 链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每 ...
- java虚拟机入门(五)- 常见垃圾回收器及jvm实现
上节讲完了垃圾回收的基础,包括java的垃圾是什么,如何寻找以及常用的垃圾回收算法,那么那么多的理论知识讲完了,具体是什么样的东西在做着回收垃圾的事情呢?我们接下来就好好聊聊jvm中常用的垃圾回收器. ...
- LDAP 简介
一.使用 Directory Services(目录服务)的目的 对于局域网内的一个用户来讲,工作等其它应用需要,我们必须凭帐号登录主机.用帐号收发E-mail,甚至为了管理需要公司还需要维护一个电子 ...
- 向数据库添加100W 条数据 性能测试
向数据库添加100W 条数据 性能测试 : 参考的相关网站目录: JDBC实现往MySQL插入百万级数据 https://www.cnblogs.com/fnz0/p/5713102.html MyS ...
- Spring Boot 两种多数据源配置:JdbcTemplate、Spring-data-jpa
多数据源配置 JdbcTemplate支持 Spring-data-jpa支持 多数据源配置 创建一个Spring配置类,定义两个DataSource用来读取application.propertie ...
- stop脚本
PID=$(ps -ef | grep eladmin-system-2.0.jar | grep -v grep | awk '{ print $2 }')if [ -z "$PID&qu ...