传送门

题目大意

给定$n$个点$m$条边的无向图,有$K$个关键点,你要尽可能的让这些关键点两两匹配,使得所有点对之间可以通过简单路径连接且任意两个简单路径没有重复的边(可以是共同经过一个点),输出每一条这样的路径。

$K\leq n,m\leq 5\times 10^4$

题解

很显然对于每一个连通块,当且仅当它有奇数个关键点,那么它会有一个关键点没有被配对,否则一定可以满足两两配对。

考虑该联通块的任意一棵生成树,不考虑是否经过了同一条边,任意两两沿着树上简单路径染边。

若有$(a,b)\cap (c,d) = (p,q)$其中$(x,y)$表示从$x,y$之间的简单路径(设$a,c$在$p$的同侧)。

那么只需要令$a,c$配对,$c,d$配对即可。

至于方案数,任意选择一棵生成树进行搜索即可,$G_x$表示以$x$为根的子树内没有配对的点是多少(若没有则$G_x=0$)。

枚举$x$的每个儿子$v$,若$G_v=0$就忽略,否则,若$G_x=0$,那么令$G_x=G_v$,不然就新建一条以$x$为$lca$的,一端是$G_x$一端是$G_v$的路径,再让$G_x=0$即可。

复杂度$O(n)$。

#include<bits/stdc++.h>
#define LL long long
#define M 100020
using namespace std;
namespace IO{
const int BS=(1<<20)+5; int Top=0;
char Buffer[BS],OT[BS],*OS=OT,*HD,*TL,SS[20]; const char *fin=OT+BS-1;
char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);} return (HD==TL)?EOF:*HD++;}
void flush(){fwrite(OT,1,OS-OT,stdout);}
void Putchar(char c){*OS++ =c;if(OS==fin)flush(),OS=OT;}
void write(int x){
if(!x){Putchar('0');return;} if(x<0) x=-x,Putchar('-');
while(x) SS[++Top]=x%10,x/=10;
while(Top) Putchar(SS[Top]+'0'),--Top;
}
int read(){
int nm=0,fh=1; char cw=Getchar();
for(;!isdigit(cw);cw=Getchar()) if(cw=='-') fh=-fh;
for(;isdigit(cw);cw=Getchar()) nm=nm*10+(cw-'0');
return nm*fh;
}
}
using namespace IO;
int n,K,m,fs[M],to[M],G[M],nt[M],fa[M],u[M],v[M],t[M],tot,tmp;
int s1[M],s2[M]; bool vs[M];
#define link(a,b) nt[tmp]=fs[a],fs[a]=tmp,to[tmp++]=b
#define ins(a,b,c) tot++,u[tot]=a,v[tot]=b,t[tot]=c
void dp(int x){
G[x]=vs[x]?x:0;
for(int i=fs[x];i!=-1;i=nt[i]){
if(fa[to[i]]) continue;
fa[to[i]]=x,dp(to[i]);
if(!G[to[i]]) continue;
if(!G[x]) G[x]=G[to[i]];
else ins(G[x],G[to[i]],x),G[x]=0;
}
}
void opt(int x,int y,int k){
int tp1=0,tp2=0;
while(x!=k) s1[++tp1]=x,x=fa[x];
while(y!=k) s2[++tp2]=y,y=fa[y];
write(tp1+tp2),Putchar(' ');
for(int i=1;i<=tp1;i++) write(s1[i]),Putchar(' '); write(k);
for(int i=tp2;i>=1;i--) Putchar(' '),write(s2[i]); Putchar('\n');
}
int main(){
n=read(),m=read(),K=read(),memset(fs,-1,sizeof(fs));
for(int i=1;i<=m;i++){int x=read(),y=read();link(x,y),link(y,x);}
for(int i=1;i<=K;i++) vs[read()]=true;
for(int i=1;i<=n;i++) if(!fa[i]) fa[i]=i,dp(i);
write(tot),Putchar('\n');
for(int i=1;i<=tot;i++) opt(u[i],v[i],t[i]);
flush(); return 0;
}

  

CodeForces 589H Tourist Guide的更多相关文章

  1. [uva] 10099 - The Tourist Guide

    10099 - The Tourist Guide 题目页:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemi ...

  2. UVa10099_The Tourist Guide(最短路/floyd)(小白书图论专题)

    解题报告 题意: 有一个旅游团如今去出游玩,如今有n个城市,m条路.因为每一条路上面规定了最多可以通过的人数,如今想问这个旅游团人数已知的情况下最少须要运送几趟 思路: 求出发点到终点全部路其中最小值 ...

  3. floyd类型题UVa-10099-The Tourist Guide +Frogger POJ - 2253

    The Tourist Guide Mr. G. works as a tourist guide. His current assignment is to take some tourists f ...

  4. codeforces 340C Tourist Problem

    link:http://codeforces.com/problemset/problem/340/C 开始一点也没思路,赛后看别人写的代码那么短,可是不知道怎么推出来的啊! 后来明白了. 首先考虑第 ...

  5. codeforces 340C Tourist Problem(公式题)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Tourist Problem Iahub is a big fan of tou ...

  6. Codeforces 732F. Tourist Reform (Tarjan缩点)

    题目链接:http://codeforces.com/problemset/problem/732/F 题意: 给出一个有n个点m条边的无向图,保证联通,现在要求将所有边给定一个方向使其变成有向图,设 ...

  7. codeforces 340C Tourist Problem(简单数学题)

    题意:固定起点是0,给出一个序列表示n个点,所有点都在一条直线上,其中每个元素代表了从起点到这个点所走的距离.已知路过某个点不算到达这个点,则从起点出发,到达所有点的方案有许多种.求所有方案走的总路程 ...

  8. CodeForces 732F Tourist Reform

    边双连通分量. 这题有一点构造的味道.一个有向图,经过强连通缩点之后会形成一个有向无环图. 如果将最大的强连通分量放在顶端,其余的强连通分量都直接或间接指向他,那么这样就构造出了符合要求的图. 接下来 ...

  9. CodeForces - 76F:Tourist (旋转坐标系,LIS)

    pro:有一个驴友,以及给定N个表演地点xi和时间ti,驴友的速度不能超过V. 问他在起点为原点和不设置起点的情况下分别最多参观多少个表演. sol:BZOJ接飞饼见过:clari也在camp的DP专 ...

随机推荐

  1. Tensorflow学习笔记(1)--安装

    安装 1.ubuntu 14.04 2. 清华大学开源软件镜像站:https://mirrors.tuna.tsinghua.edu.cn/help/tensorflow/ (要求sudo权限,如果报 ...

  2. windows下docker toolbox无法下载boot2docker.iso

    GitHub连不上导致自动更新失败.(网络形势严峻!) 通过别的途径手动下载了指定的最新的boot2docker.iso文件.(比方说迅雷!比方说迅雷!比方说迅雷!) https://github.c ...

  3. 【HackerRank】Sherlock and MiniMax

    题目连接:Sherlock and MiniMax Watson gives Sherlock an array A1,A2...AN. He asks him to find an integer  ...

  4. mysql sql的执行顺序

    转:http://blog.csdn.net/u014044812/article/details/51004754 关于sql和MySQL的语句执行顺序(必看!!!) 原创 2016年03月29日 ...

  5. 连接池Connection timed out

    当应用程序使用数据库连接池(或带服务程序的连接池)进行数据连接时,防火墙的设置有可能会导致连接出现超时或者被重置的问题.当从数据库读数据(或服务程序客户端读取数据)的时候 有可能会 Connectio ...

  6. Android系统--输入系统(三)必备Linux知识_双向通信(scoketpair)

    Android系统--输入系统(三)必备Linux知识_双向通信(scoketpair) 引入 1. 进程和APP通信 创建进程 读取.分发 - 进程发送输入事件给APP 进程读取APP回应的事件 输 ...

  7. poj 2762 Going from u to v or from v to u?【强连通分量缩点+拓扑排序】

    Going from u to v or from v to u? Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 15812 ...

  8. Could not reserve enough space for object heap解决办法

    Centos6.4  Jdk1.6 1.在终端输入Java命令报错 [root@localhost local]# java Error occurred during initialization ...

  9. firefox和chrome实现页面打印自动分页

    在Firefox和chrome中直接调用打印功能的js方法是 window.print(); 但是如果页面很长,那么就需要分页,这时只需要在页面中添加css属性即可,如果想自动分页,则如下所示 < ...

  10. Luogu-3878 [TJOI2010]分金币

    这题和在我长郡考试时的一道题思路差不多...考虑折半搜索,预处理左半边选的方案所产生的数量差值\(x\)以及价值差值\(y\),把\(y\)扔到下标为\(x\)的set里面,然后在搜索右半边,每搜出一 ...