CF700C (枚举+tarjan)
Problem Break up (CF700C)
题目大意
给一张n个点,m条边的无向图,有边权,和起点S,终点T。 (n<=1000 , m<=30000)
要求最多割掉2条边,使得S到T不连通。
输出最小代价以及方案。
解题分析
如果只是割掉1条边,那么就是求割边了。
如果要割掉2条边,一个自然的思路就是枚举一条边后再求割点,这样复杂度是O(m ^2)的,显然会超时。
再考虑并不需要枚举每一条边,只需要求一条S到T的路径,枚举这条路径上的边即可。因为若要不连通,必定要割掉这条路径上的某一条边
复杂度O(n*m)。
参考程序
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <string>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std; #define N 100008
#define V 1008
#define E 60008
#define lson l,m,rt<<1
#define rson m,r+1,rt<<1|1
#define clr(x,v) memset(x,v,sizeof(x));
#define LL long long const int mo = ;
const int inf = 0x3f3f3f3f;
const int INF = ;
/**************************************************************************/ int n,m,S,T,tmp;
int vis[V],path[V],dfn[V],low[V],road[V],bridge[E];
int ans;
int ANS[V];
struct line{
int u,v,w,nt;
}eg[E];
int sum,lt[V]; void adt(int u,int v,int w){
eg[++sum]=(line){u,v,w,lt[u]};
lt[u]=sum;
}
void add(int u,int v,int w){
adt(u,v,w); adt(v,u,w);
} bool dfs(int u){
vis[u]=;
if (u==T) return true;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (vis[v]) continue;
if (dfs(v)){
path[++path[]]=i/;
return true;
}
}
return false;
} bool dfs_2(int u,int del){
vis[u]=;
if (u==T) return true;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (i/==del) continue;
if (vis[v]) continue;
if (dfs_2(v,del)){
road[++road[]]=i/;
return true;
}
}
return false;
}
void tarjan(int u,int fa,int del){
dfn[u]=low[u]=++tmp;
int flag=;
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (i/==del) continue;
if (v==fa && !flag){
flag=;
continue;
}
if (!dfn[v]){
tarjan(v,u,del);
low[u]=min(low[u],low[v]);
if (dfn[u]<low[v]) bridge[i/]=;
}
else low[u]=min(low[u],dfn[v]);
}
} int main(){
scanf("%d %d",&n,&m);
scanf("%d %d",&S,&T);
sum=;
for (int i=;i<=m;i++){
int u,v,w;
scanf("%d %d %d",&u,&v,&w);
add(u,v,w);
} clr(vis,);
clr(path,);
if (!dfs(S)) { printf("0\n0\n"); return ; }
else
{
ans=INF;
for (int ii=;ii<=path[];ii++){
clr(bridge,);
clr(vis,);
clr(road,);
clr(dfn,);
tmp=;
for (int i=;i<=n;i++)
if (!dfn[i])
tarjan(i,,path[ii]);
if (!dfs_2(S,path[ii])){
if (eg[path[ii]*].w<ans){
ans = eg[path[ii]*].w;
ANS[]=;
ANS[]=path[ii];
}
}
else
{
for (int i=;i<=road[];i++){
if (bridge[road[i]]){
if (eg[road[i]*].w+eg[path[ii]*].w<ans){
ans=eg[road[i]*].w+eg[path[ii]*].w;
ANS[]=;
ANS[]=road[i];
ANS[]=path[ii];
}
}
}
}
}
if (ans==INF) printf("-1\n");
else
{
printf("%d\n%d\n",ans,ANS[]);
for (int i=;i<=ANS[];i++) printf("%d%c",ANS[i],i!=ANS[]?' ':'\n');
}
}
}
CF700C (枚举+tarjan)的更多相关文章
- poj3713 Transferring Sylla 枚举+tarjan判割点
其实就是判断是否为三连通图 三连通图指的是去掉3个点就不连通的图,但是并没有直接求三连通的算法.著名的Tarjan算法可以求解连通和割点,再枚举删除一个点就能达到三连通的目的. 先看用例2,是由用例1 ...
- 有向图强连通分量的Tarjan算法
有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G ...
- [学习笔记]tarjan求割点
都口胡了求割边,就顺便口胡求割点好了QAQ 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访问,并在回溯后更新 2.如果某个邻接点已被访问过,则更新 对于当前 ...
- [学习笔记]tarjan求割边
上午打模拟赛的时候想出了第三题题解,可是我不会求割边只能暴力判割边了QAQ 所以,本文介绍求割边(又称桥). 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访 ...
- 【BZOJ-1179】Atm Tarjan + SPFA
1179: [Apio2009]Atm Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 2407 Solved: 993[Submit][Status ...
- 强连通分量的Tarjan算法
资料参考 Tarjan算法寻找有向图的强连通分量 基于强联通的tarjan算法详解 有向图强连通分量的Tarjan算法 处理SCC(强连通分量问题)的Tarjan算法 强连通分量的三种算法分析 Tar ...
- code vs1506传话(塔尖)+tarjan图文详解
1506 传话 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 白银 Silver 题解 题目描述 Description 一个朋友网络,如果a认识b,那么如果a第一次收到 ...
- [知识点]Tarjan算法
// 此博文为迁移而来,写于2015年4月14日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102vxnx.html UPD ...
- 【Tarjan】+【SPFA】APIO2009 Atm
一.算法介绍 tarjan——求解有向图强连通分量.这个算法在本人的一篇blog中有介绍,这里就不赘述了.贴上介绍tarjan的的blog链接:http://www.cnblogs.com/Maki- ...
随机推荐
- 如何在Objective-C中实现链式语法
在接触到开源项目 Masonry 后,里面的布局约束的链式写法让我颇感兴趣,就像下面这样: 1 2 3 4 5 6 7 8 UIEdgeInsets padding = UIEdgeInsetsMak ...
- Visual Studio 2012出现“无法访问T-SQL组件和安装了不兼容伯 DacFx版本”的解决办法
参考:Visual Studio 2012出现“无法访问T-SQL组件和安装了不兼容伯 DacFx版本”的解决办法 Vs2012的下载地址: https://msdn.microsoft.com/en ...
- 转载css层级优先级。
解读CSS样式优先级(修改门户自定义样式必读) 一.什么是CSS优先级?所谓CSS优先级,即是指CSS样式在浏览器中被解析的先后顺序.当同一个元素(或内容)被多个CSS选择符选中时,就要按照优先权取舍 ...
- js仿京东轮播图效果
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- LinearLayout练习
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- Ubuntu14.04安装和配置ROS Indigo(一)
安装ROS 配置Ubuntu的软件源 配置Ubuntu要求允许接受restricted.universe和multiverse的软件源,可以根据下面的链接配置: https://help.ubuntu ...
- [ASP.NET] 使用Loading遮罩防止使用者重複點擊
From: http://www.dotblogs.com.tw/joysdw12/archive/2012/12/13/85629.aspx 前言 在網頁執行中可能會因為資料量大或其他原因影響使用者 ...
- sql 行专列 列转行 普通行列转换
转载:http://www.cnblogs.com/newwind521/archive/2010/11/25/1887203.html sql 行专列 列转行 普通行列转换 /* 标题:普通行列转换 ...
- UVA 10294 等价类计数
题目大意: 项链和手镯都是若干珠子穿成的环形首饰,手镯可以旋转和翻转,但项链只能旋转,给n个珠子,t种颜色,求最后能形成的手镯,项链的数量 这里根据等价类计数的polya定理求解 对于一个置换f,若一 ...
- source 命令与“ . ”点命令
http://wenku.baidu.com/link?url=r3_WjJwQziv5wooIiatYbIMotPHcop56ZyakNGFor5DgJLQD-orAwVmOwp80RAnJ3tRD ...