HINT

注意是全程不能经过两个相同的景点,并且一天的开始和结束不能用同样的交通方式。

[吐槽]

  嗯。。看到这题的想法的话。。先想到了每个点的度为2,然后就有点不知所措了

  隐隐约约想到了网络流,但并没有继续往下想了。。。

  听完学长的讲评之后(%xj)个人觉得建图还是很有意思的ovo

[题解]

  因为每个点到对面都有k种方式,那就想到每个点原来的点$x_0$拆成k个点$x_1$, $x_2$, $x_3$... $x_k$

  然后很自然地$x_0$和拆成的点之间要连边

  容量的话,因为hint里面的限制,也就是说一个点到另一个点的k中交通方式中只能选一种

  (因为每个点只能到一次,而开始和结束不能用同样的方式)

  这样一来容量显然就应该是1了

  两岸之间的连接,就直接按照读入左岸连到右岸就好,容量也为1

  (但其实因为左岸的流入流量和右岸的流出流量都有限制,中间的那条好像容量取1~ $\infty$都可以。。。%yxq)

  接着考虑最后的答案是怎么得到的,会发现其实我们最后的到的路线是若干个环,每个点的度为2(一个大概长这样的)

  

  如此一来,就会有个大胆的想法

  对于每一个左岸的$x_0$,我们连一条源点到它的容量为2的边

  对于每一个右岸的$x_0$,我们连一条它到汇点的容量为2的边

  这样起到一个限制了每个点的度的作用,就可以保证有环并且环内每个点的度都为2(个人感觉这点是很有意思的)

  

  于是乎最终的到的图长这样(以样例为例)

  

  那么现在考虑构造方案

  看回之前建图的思路,很容易得到的一个结论是满流的边肯定就是要走的边

  那么现在问题就变成知道一堆边然后构造方案啦

  很简单粗暴的方法直接强行把每个环走一遍记录下答案就好

  天数的话就看有多少个环就好啦

  挫挫的代码qwq

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define inf 2147483647
using namespace std;
const int MAXN=**+;
struct xxx
{
int y,next,op,r,x;
}a[MAXN*];
queue<int> q;
int h[MAXN],lv[MAXN],id[][],num[MAXN];
int go[MAXN][],ans[][];
bool vis[MAXN];
int n,m,k,vs,vt,tot,tot1;
int add(int x,int y,int r);
int bfs();
int dfs(int v,int o);
int get_ans(); int main()
{
freopen("a.in","r",stdin); int x,y,z;
scanf("%d%d%d",&n,&m,&k);
memset(h,-,sizeof(h));
tot=;
vs=,vt=MAXN-;
for (int i=;i<=n+n;++i)
for (int j=;j<=k;++j)
id[i][j]=++tot,num[tot]=i;
tot=;
for (int i=;i<=n;++i)
{
add(vs,id[i][],);
add(id[i+n][],vt,);
for (int j=;j<=k;++j)
add(id[i][],id[i][j],),add(id[i+n][j],id[i+n][],);
}
for (int i=;i<=m;++i)
{
scanf("%d%d%d",&x,&y,&z);
add(id[x][z],id[y+n][z],);
}
while (bfs()) dfs(vs,inf);
get_ans();
} int add(int x,int y,int r)
{
a[++tot].y=y; a[tot].next=h[x]; h[x]=tot; a[tot].r=r; a[tot].op=tot+;
a[++tot].y=x; a[tot].next=h[y]; h[y]=tot; a[tot].r=; a[tot].op=tot-;
} int bfs()
{
while (!q.empty()) q.pop();
memset(lv,,sizeof(lv));
q.push(vs);
lv[vs]=;
int v,u;
while (!q.empty())
{
v=q.front(); q.pop();
for (int i=h[v];i!=-;i=a[i].next)
{
u=a[i].y;
if (lv[u]||!a[i].r) continue;
q.push(u);
lv[u]=lv[v]+;
if (u==vt) return true;
}
}
return false;
} int dfs(int v,int o)
{
if (v==vt||o==) return o;
int u,flow,ret=;
for (int i=h[v];i!=-;i=a[i].next)
{
u=a[i].y;
if (lv[u]!=lv[v]+) continue;
flow=dfs(u,min(a[i].r,o));
if (flow)
{
a[i].r-=flow;
a[a[i].op].r+=flow;
ret+=flow;
o-=flow;
if (!o) break;
}
}
return ret;
} int get_ans()
{
int x,y,pre;
//go[i]记录与i相连的两个点
for (int i=;i<=n;++i)
for (int j=;j<=k;++j)
for (int tmp=h[id[i][j]];tmp!=-;tmp=a[tmp].next)
{
if (a[tmp].r||a[tmp].y==id[i][]) continue;
y=num[a[tmp].y];
if (!go[i][]) go[i][]=y;
else go[i][]=y; if (!go[y][]) go[y][]=i;
else go[y][]=i;
}
memset(vis,false,sizeof(vis));
int cnt=;
for (int i=;i<=n;++i)
{
if (vis[i]) continue;
++cnt;
//将每个环走一遍
pre=i,x=go[i][];
ans[cnt][++ans[cnt][]]=i;
vis[i]=true;
while (x!=i)
{
vis[x]=true;
ans[cnt][++ans[cnt][]]=x;
if (pre==go[x][]) pre=x,x=go[x][];
else pre=x,x=go[x][];
}
ans[cnt][++ans[cnt][]]=x;
}
printf("%d\n",cnt);
//因为建图的方式所以左右岸肯定是交错来的
for (int i=;i<=cnt;++i)
{
printf("%d ",ans[i][]);
for (int j=;j<=ans[i][];++j)
if (j&) printf("L%d ",ans[i][j]);
else printf("R%d ",ans[i][j]-n);
printf("\n");
}
}

【2016北京集训测试赛】river的更多相关文章

  1. 2016北京集训测试赛(十六)Problem B: river

    Solution 这题实际上并不是构造题, 而是一道网络流. 我们考虑题目要求的一条路径应该是什么样子的: 它是一个环, 并且满足每个点有且仅有一条出边, 一条入边, 同时这两条边的权值还必须不一样. ...

  2. 【2016北京集训测试赛(十六)】 River (最大流)

    Description  Special Judge Hint 注意是全程不能经过两个相同的景点,并且一天的开始和结束不能用同样的交通方式. 题解 题目大意:给定两组点,每组有$n$个点,有若干条跨组 ...

  3. 【2016北京集训测试赛(十)】 Azelso (期望DP)

    Time Limit: 1000 ms   Memory Limit: 256 MB Description 题解 状态表示: 这题的状态表示有点难想...... 设$f_i$表示第$i$个事件经过之 ...

  4. 【2016北京集训测试赛(二)】 thr (树形DP)

    Description 题解 (这可是一道很早就碰到的练习题然后我不会做不想做,没想到在Contest碰到欲哭无泪......) 题目大意是寻找三点对的个数,使得其中的三个点两两距离都为d. 问题在于 ...

  5. 【2016北京集训测试赛(八)】 crash的数列 (思考题)

    Description 题解 题目说这是一个具有神奇特性的数列!这句话是非常有用的因为我们发现,如果套着这个数列的定义再从原数列引出一个新数列,它居然还是一样的...... 于是我们就想到了能不能用多 ...

  6. 【2016北京集训测试赛】azelso

    [吐槽] 首先当然是要orzyww啦 以及orzyxq奇妙顺推很强qwq 嗯..怎么说呢虽然说之前零零散散做了一些概d的题目但是总感觉好像并没有弄得比较明白啊..(我的妈果然蒟蒻) 这题的话可以说是难 ...

  7. [2016北京集训测试赛17]crash的游戏-[组合数+斯特林数+拉格朗日插值]

    Description Solution 核心思想是把组合数当成一个奇怪的多项式,然后拉格朗日插值..:哦对了,还要用到第二类斯特林数(就是把若干个球放到若干个盒子)的一个公式: $x^{n}=\su ...

  8. [2016北京集训测试赛15]statement-[线段树+拆环]

    Description Solution 由于题目要求,将a[i]->b[i](边权为i)后所得的图应该是由森林和环套树组合而成. 假如是树形结构,所有的t[i]就直接在线段树t[i]点的dfs ...

  9. [2016北京集训测试赛5]小Q与内存-[线段树的神秘操作]

    Description Solution 哇真的异常服气..线段树都可以搞合并和拆分的啊orzorz.神的世界我不懂 Code #include<iostream> #include< ...

随机推荐

  1. Zabbix 3.0 监控Web

    zabbix 界面配置 触发器添加

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

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

  3. 解决java.lang.IllegalStateException: BeanFactory not initialized or already closed - call 'refresh' before accessing beans via the ApplicationContext这个问题

    今天在运行别人的SSH项目时,遇到了这个问题 严重: Exception sending context initialized event to listener instance of class ...

  4. PHP实现WebService的简单示例和实现步骤

    首先我创建的文件有: api.php api的接口类文件 api.wsdl 我创建产生的最后要调用的接口文件 cometrue.php 注册service api类内容的所有内容的执行文件 creat ...

  5. os模块中关于文件/目录常用的函数使用方法

    os模块中关于文件/目录常用的函数使用方法 函数名 使用方法 getcwd() 返回当前工作目录 chdir(path) 改变工作目录 listdir(path='.') 列举指定目录中的文件名('. ...

  6. Java经典编程题50道之四十八

    某个公司采用公用电话传递数据,数据是四位的整数,在传递过程中是加密的,加密规则如下: 每位数字都加上5,然后用和除以10的余数代替该数字, 再将第一位和第四位交换,第二位和第三位交换. public ...

  7. php进阶之路--转载

    之前有看过相关的文章,觉得还是这篇详细点,有具体的目标实现起来才更有动力 转载自:http://wen.52fhy.com/2016/2016-09-03-PHP-cheng-xu-yuan-xue- ...

  8. 在Centos环境下安装兼容Apache2.4高版本SVN服务

    在阿里云Centos环境下,搭建PHP运行环境,PHP选择了php7版本,Mysql选择了5.7版本,Apache选择了2.4版本,在搭建SVN版本控制服务过程中出现了不兼容问题,当前环境下Apach ...

  9. UVA1601 状态搜索

    很有意思的一道题,就是迷宫问题的增强版.但是细节很多,有一个技巧就是把每个可以走的位置编号方便状态判重. AC代码: #include<cstdio> #include<cstrin ...

  10. ES6的介绍和常用语法

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 前言 ECMAScript 是 JS 的语言标准.而 ES6 是新的 J ...