jzoj3577 [CEOI2011]Traffic 强连通分量缩点
来源:互联网 发布:impress.js demo 编辑:程序博客网 时间:2024/05/16 19:21
Description
Gdynia 的中心坐落于Kacza 河中游的一个岛屿上。每天早晨,成千辆小车从河流的西岸的住宅区出发穿过岛屿(使用连接岛西路口的桥梁)到达东岸的工业区(使用连接岛东路口的桥梁)。
这个岛屿酷似一个边平行于坐标轴的矩形。因此,我们视他为一个笛卡尔坐标系上的A*B的矩形,对角的坐标为(0,0) 和(A,B)。
在这个岛屿上,有n 个路口从1 到n 编号。路口i 位于坐标(xi; yi)。如果一个路口坐标类似于(0,y),那么它在岛西。类似的,坐标形于(A,y) 的路口坐落在岛东。路口通过街道连接起来。每一条街道是一条连接两个路口的线段。街道可以是双向或者单向的。没有两条街道有公共点(除了作为线段端点的路口)。岛上没有桥或者地道。其他的道路网络形状是不被认可的。特别的是,街道可以与岛屿的边缘重合,或者存在没有连接街道的路口。
因为交通密度不断增长,所以市长雇佣你去检查现在的道路网络是否足够。他要求你写一个程序,确定从每个岛西的路口出发能到达多少个岛东的路口。
Solution
注意到一个条件是没有两条边相交,那么我们把东岸的点按y坐标降序排列后,任意一个西岸的点能到达的东岸一定是连续的一段。tarjan缩点之后求出一个起点能到达的最大和最小标号的终点即可
本来还以为会爆栈的= =!
Code
#include <stdio.h>#include <string.h>#include <stack>#include <algorithm>#include <queue>#define rep(i,st,ed) for (int i=st;i<=ed;++i)#define fill(x,t) memset(x,t,sizeof(x))#define read2(x,y) read(x),read(y)#define read3(x,y,z) read(x),read(y),read(z)#define max(x,y) ((x)>(y)?(x):(y))#define min(x,y) ((x)<(y)?(x):(y))#define INF 0x3f3f3f3f#define N 600001#define E 4000001struct edge{int x,y,next;}e[E];struct pos{int x,y;}p[N];std:: queue<int>que;std:: stack<int>stack;int id[N],inStack[N],dfn[N],low[N],scc[N],data[N],vis[N];int mn[N],mx[N];int ls[N],edCnt=0;int n,m,A,B;void read(int &x) { x=0; int v=1; char ch=getchar(); for (;ch<'0'||ch>'9';v=(ch=='-')?(-1):(v),ch=getchar()); for (;ch<='9'&&ch>='0';x=x*10+ch-'0',ch=getchar()); x*=v;}void addEdge(int x,int y) { e[++edCnt]=(edge){x,y,ls[x]}; ls[x]=edCnt;}void dfs(int now) { if (vis[now]) return ; vis[now]=1; for (int i=ls[now];i;i=e[i].next) dfs(e[i].y);}void tarjan(int now) { stack.push(now); inStack[now]=1; dfn[now]=low[now]=++dfn[0]; for (int i=ls[now];i;i=e[i].next) { if (!dfn[e[i].y]) { tarjan(e[i].y); low[now]=min(low[now],low[e[i].y]); } else if (!scc[e[i].y]) { low[now]=min(low[now],dfn[e[i].y]); } } if (dfn[now]==low[now]) { ++scc[0]; mx[scc[0]]=-INF; mn[scc[0]]=INF; for (int tmp=0;tmp!=now;) { tmp=stack.top(); stack.pop(); if (id[tmp]) { mx[scc[0]]=max(mx[scc[0]],id[tmp]); mn[scc[0]]=min(mn[scc[0]],id[tmp]); } scc[tmp]=scc[0]; inStack[tmp]=0; } }}bool cmp(int a,int b) {return p[a].y>p[b].y;}void dp(int now) { if (vis[now]) return ; vis[now]=1; for (int i=ls[now];i;i=e[i].next) { dp(e[i].y); mx[now]=max(mx[now],mx[e[i].y]); mn[now]=min(mn[now],mn[e[i].y]); }}int main(void) { read2(n,m); read2(A,B); rep(i,1,n) {read2(p[i].x,p[i].y);} rep(i,1,m) { int x,y,opt; read3(x,y,opt); addEdge(x,y); if (opt!=1) {addEdge(y,x);} } int cnt=0; rep(i,1,n) if (!p[i].x) dfs(i); rep(i,1,n) if (p[i].x==A&&vis[i]) data[++cnt]=i; std:: sort(data+1,data+cnt+1,cmp); rep(i,1,cnt) {id[data[i]]=i;} rep(i,1,n) if (!dfn[i]) {tarjan(i);} fill(ls,0); int tmp=edCnt; rep(i,1,tmp) if (scc[e[i].x]!=scc[e[i].y]) { addEdge(scc[e[i].x],scc[e[i].y]); } fill(vis,0); rep(i,1,scc[0]) dp(i); cnt=0; rep(i,1,n) if (!p[i].x) {data[++cnt]=i;} std:: sort(data+1,data+cnt+1,cmp); rep(i,1,cnt) { printf("%d\n", max(0,mx[scc[data[i]]]-mn[scc[data[i]]]+1)); } return 0;}
阅读全文
0 0
- jzoj3577 [CEOI2011]Traffic 强连通分量缩点
- bzoj 2387: [Ceoi2011]Traffic 强连通分量+dp
- JZOJ3577. 【CEOI2011】Traffic
- 强连通分量缩点
- 强连通分量缩点
- 强连通分量 + 缩点 kosaraju
- 强连通分量缩点的模板
- POJ2186 Tarjan强连通分量+缩点
- 强连通分量+缩点-poj1236
- 强连通分量+缩点uva12167
- poj 2186 强连通分量 缩点
- poj 1236 强连通分量 缩点
- 强连通分量+缩点(poj2553)
- poj1236强连通分量+缩点
- hdu 4635 强连通分量+缩点
- POJ2186Popular Cows(强连通分量+缩点)
- poj 1236 强连通分量+缩点
- poj1236 强连通分量+缩点
- FileSystemWatcher 的使用
- 2017年的阅读总结
- PTA一周练(第一周)记录
- 链表操作之删除重复元素
- Hdoj 2668 Daydream
- jzoj3577 [CEOI2011]Traffic 强连通分量缩点
- Java多线程系列--【基础篇07】- 线程休眠
- LeetCode小白菜笔记[8]:Remove Duplicates from Sorted Array
- leetcode 518. Coin Change 2 动态规划DP
- html5-服务端数据推送简记
- 成员变量与局部变量的区别:
- 2017-2018noip复习计划
- STM32启动过程解读与跟踪验证
- python读conf配置文件--ConfigParser