JSOI2012越狱老虎桥
Posted shxnb666
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JSOI2012越狱老虎桥相关的知识,希望对你有一定的参考价值。
题面
https://www.luogu.org/problem/P5234
题解
首先先求割边,割掉的肯定是一条割边。
又因为敌人会加固一条链,所以这条链上的边肯定不能割,我们只需要按权值从小到大加入每一条割边,然后看看敌人什么时候兼顾不上就行了。
判断加入的边是否在已经确定的链上,本来应该无根树转有根树然后通过$LCA$分类讨论的,我懒得写了,写了个爆搜,复杂度是假的,但是跑的快。
#include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 500500 #define M 1000500 #define mod 1000000007 #define ri register int using namespace std; inline int read() int ret=0; char ch=getchar(); while (ch<‘0‘ || ch>‘9‘) ch=getchar(); while (ch>=‘0‘ && ch<=‘9‘) ret*=10,ret+=(ch-‘0‘),ch=getchar(); return ret; vector<int> ed[N],tr[N]; int to[M<<1],isb[M<<1],t[M],id[M]; int dfn[N],low[N],y_clock,col[N]; void tarjan(int x,int ff) dfn[x]=low[x]=++y_clock; for (ri i=0;i<ed[x].size();i++) int e=ed[x][i]; int y=to[e]; if (y==ff) continue; if (!dfn[y]) tarjan(y,x); low[x]=min(low[x],low[y]); if (low[y]>dfn[x]) isb[e]=isb[e^1]=1; else low[x]=min(low[x],dfn[y]); void dfs(int x,int c) col[x]=c; for (ri i=0;i<ed[x].size();i++) int e=ed[x][i]; if (isb[e]) continue; if (col[to[e]]!=c) dfs(to[e],c); bool is_bridge(int e) return isb[(e-1)<<1]; bool cmp(int a,int b) if (is_bridge(a)==is_bridge(b)) return t[a]<t[b]; else return is_bridge(a)>is_bridge(b); bool dfs2(int x,int ff,int &u,int &fau,int a,int b) if (x==a || x==b) if (x==a) fau=a,u=b; else fau=b,u=a; return 1; for (ri i=0;i<tr[x].size();i++) int y=tr[x][i]; if (y==ff) continue; if (dfs2(y,x,u,fau,a,b)) return 1; return 0; int main() int n=read(),m=read(); int cc=-1; for (ri i=1;i<=m;i++) int u=read(),v=read(); t[i]=read(); ed[u].push_back(++cc); to[cc]=v; ed[v].push_back(++cc); to[cc]=u; for (ri i=1;i<=n;i++) if (!dfn[i]) tarjan(i,-1); int cn=0; for (ri i=1;i<=n;i++) if (!col[i]) dfs(i,++cn); for (ri i=1;i<=m;i++) id[i]=i; sort(id+1,id+1+m,cmp); for (ri i=1;i<=m;i++) if (!is_bridge(id[i])) break; int e=(id[i]-1)<<1; tr[col[to[e]]].push_back(col[to[e^1]]); tr[col[to[e^1]]].push_back(col[to[e]]); if (!is_bridge(id[1])) puts("-1"); return 0; int ee=(id[1]-1)<<1; int u=col[to[ee]],fau=col[to[ee^1]]; int v=col[to[ee^1]],fav=col[to[ee]]; for (ri i=2;i<=m;i++) if (!is_bridge(id[i])) break; int e=(id[i]-1)<<1; if (!dfs2(u,fau,u,fau,col[to[e]],col[to[e^1]]) && !dfs2(v,fav,v,fav,col[to[e]],col[to[e^1]])) printf("%d\n",t[id[i]]); return 0; puts("-1"); return 0;
以上是关于JSOI2012越狱老虎桥的主要内容,如果未能解决你的问题,请参考以下文章