题意:

在一个\(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(费用流路径)题解的更多相关文章

  1. 洛谷P4014 分配问题【最小/大费用流】题解+AC代码

    洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...

  2. 洛谷 P4016负载平衡问题【费用流】题解+AC代码

    洛谷 P4016负载平衡问题 P4014 分配问题[费用流]题解+AC代码 负载平衡问题 题目描述 GG 公司有n个沿铁路运输线环形排列的仓库,每个仓库存储的货物数量不等.如何用最少搬运量可以使 n ...

  3. POJ 3422 Kaka's Matrix Travels(拆点+最大费用流)题解

    题意:小A从左上角走到右下角,每个格子都有一个价值,经过这个格子就把价值拿走,每次只能往下或往右走,问你走k次最多能拿多少价值的东西. 思路:这里有一个限制条件就是经过之后要把东西拿走,也就是每一格的 ...

  4. LightOJ 1071 Baker Vai(拆点+最大费用流)题解

    题意:给一个n*m的方格,每个格子上都有一个数字表示价值,小A在左上角,他从左上角走到右下角只能向右或向下走,然后再从右下角走上左上角,这次只能向上或向左走,这两条路绝对没有重复,问你怎样走有最大价值 ...

  5. 【费用流】【CODEVS】1227 方格取数2

    [算法]最小费用最大流(费用流) [题解] 费用流:http://www.cnblogs.com/onioncyc/p/6496532.html 本题构图: 在有限的k次行走中尽可能多的拿到数字,明显 ...

  6. 【网络流24题】No.21 (最长 k 可重区间集问题 最长不相交路径 最大费用流)

    [] 输入文件示例input.txt4 21 76 87 109 13 输出文件示例output.txt15 [分析] 直接co题解好了,写得挺全.. [建模方法] 方法1 按左端点排序所有区间,把每 ...

  7. 网络费用流-最小k路径覆盖

    多校联赛第一场(hdu4862) Jump Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  8. BZOJ.1927.[SDOI2010]星际竞速(无源汇上下界费用流SPFA /最小路径覆盖)

    题目链接 上下界费用流: /* 每个点i恰好(最少+最多)经过一次->拆点(最多)+限制流量下界(i,i',[1,1],0)(最少) 然后无源汇可行流 不需要源汇. 注: SS只会连i',求SS ...

  9. 【洛谷2469/BZOJ1927】[SDOI2010]星际竞速(费用流/最小路径覆盖)

    题目: 洛谷2469 分析: 把题目翻译成人话:给一个带边权的DAG,求一个路径覆盖方案使路径边权总和最小.从点\(i\)开始的路径需要额外加上\(A_i\)的权值. 回xian忆chang一xue下 ...

随机推荐

  1. 解决JS获取中文参数出现的乱码问题

    在代码中增加如下js函数: function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + " ...

  2. ElasticSearch Python 基本操作

    创建索引 from elasticsearch import Elasticsearch es = Elasticsearch('192.168.149.96:9200') mappings = { ...

  3. EasyUI框架

    使用EasyUI框架时,需要导入3个包在项目js文件夹之中. 在项目之中,每次需先引入相关文件: <!--引入jquery--> <script src="../js/jq ...

  4. Spark获取DataFrame中列的方式--col,$,column,apply

    Spark获取DataFrame中列的方式--col,$,column,apply 1.官方说明 2.使用时涉及到的的包 3.Demo 原文作者:大葱拌豆腐 原文地址:Spark获取DataFrame ...

  5. Spark DataSource Option 参数

    Spark DataSource Option 参数 1.parquet 2.orc 3.csv 4.text 5.jdbc 6.libsvm 7.image 8.json 9.xml 9.1读选项 ...

  6. RESTFul应用分析

    Restful API 近年来应用越来越广泛,各大互联网公司纷纷推出了自己的 Restful API 服务. 本文将从实际应用出发,从 REST 到 Restful 再到 Restful API ,逐 ...

  7. Flink-v1.12官方网站翻译-P028-Custom Serialization for Managed State

    管理状态的自定义序列化 本页面的目标是为需要使用自定义状态序列化的用户提供指导,涵盖了如何提供自定义状态序列化器,以及实现允许状态模式演化的序列化器的指南和最佳实践. 如果你只是简单地使用Flink自 ...

  8. SDNUOJ1016矩形合并

    传送门 题意: 给出n个矩形,把重合的矩形归成一个图形,问合并以后剩下几个图形 思路: 我开始想用dfs,但是发现不太行. 后来知道才是并查集 Orz 用一个结构体数组存矩形的左下角和右上角的坐标,再 ...

  9. 浅谈Webpack模块打包工具一

    为什么要使用模块打包工具 1.模块化开发ES Modules存在兼容性问题 打包之后成产阶段编译为ES5 解决兼容性问题 2.模块文件过多 网络请求频繁  开发阶段把散的模块打包成一个模块 解决网络请 ...

  10. shell编程基础一

    1.定义变量 a=1 shell定义变量要注意等号前后不能有空格,不然会报错,请严格按照格式编写. 2.打印输出 echo 1 使用echo打印,后面留一个空格. 3.shell中通过 ${变量名} ...