n<=1000,m<=30000的图,问割掉边权和尽量小的0、1或2条边使S和T不连通,输出割了哪些边,无解-1.

道理是很好懂的,先随便找S到T的一条路径,找不到输出0,找到的话这条路上至少有一条边要删,那枚举一下割谁,对剩下的图再做tarjan即可。复杂度(n*m)。

然而!!写起来是很难写的。。

方法一:一开始把所有S到T的路径上的边都标记好,枚举割的第一条边后跑完tarjan,直接看这些边会不会是割边再取min即可。

方法二:枚举割的第一条边后,tarjan求个边双,然后缩起来建树,在树上搜一次。

方法二。

 #include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<vector>
//#include<assert.h>
#include<algorithm>
//#include<iostream>
using namespace std; int n,m,s,t;
#define maxn 1011
#define maxm 60011
struct Edge{int to,v,next;}edge[maxm]; int first[maxn],le=;
void in(int x,int y,int v) {Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
void insert(int x,int y,int v) {in(x,y,v); in(y,x,v);} int list[maxn],ll=,ans,numofans,whoisans[];
bool vis[maxn];
bool dfs(int x)
{
if (x==t) return ;
vis[x]=;
for (int i=first[x];i;i=edge[i].next)
{
const Edge &e=edge[i]; if (vis[e.to]) continue;
list[++ll]=i>>;
if (dfs(e.to)) return ;
ll--;
}
return ;
} int bel[maxn],tot,Time,low[maxn],dfn[maxn],sta[maxn],top;
struct Tree
{
struct Edge{int to,v,id,next;}edge[maxm]; int first[maxn],le;
void in(int x,int y,int v,int id) {Edge &e=edge[le];e.to=y;e.v=v;e.id=id;e.next=first[x];first[x]=le++;}
void insert(int x,int y,int v,int id) {in(x,y,v,id); in(y,x,v,id);}
bool vis[maxn],ok; int select,selectv;
void clear()
{
memset(vis,,sizeof(vis)); ok=;
memset(first,,sizeof(first)); le=;
}
void dfs(int x,int fa,int Min,int Minid)
{
if (ok) return;
if (x==bel[t])
{
ok=;
if (selectv+Min<ans)
{
ans=selectv+Min;
numofans=;
whoisans[]=select; whoisans[]=Minid;
}
return;
}
vis[x]=;
for (int i=first[x];i && !ok;i=edge[i].next)
{
const Edge &e=edge[i]; if (vis[e.to]) continue;
dfs(e.to,x,min(Min,e.v),e.v<Min?e.id:Minid);
}
}
}T; void tarjan(int x,int f,int who)
{
low[x]=dfn[x]=++Time; sta[++top]=x; vis[x]=;
for (int i=first[x];i;i=edge[i].next)
{
if (i==f || i==(f^) || i==(who<<) || i==((who<<)^)) continue;
const Edge &e=edge[i];
if (!dfn[e.to]) tarjan(e.to,i,who),low[x]=min(low[x],low[e.to]);
else if (vis[e.to]) low[x]=min(low[x],dfn[e.to]);
}
if (low[x]==dfn[x])
{
tot++;
while (sta[top]!=x) bel[sta[top]]=tot,vis[sta[top--]]=;
bel[sta[top--]]=tot,vis[x]=;
}
} void tarjan(int select)
{
top=tot=Time=;
memset(dfn,,sizeof(dfn));
memset(vis,,sizeof(vis));
for (int i=;i<=n;i++) if (!dfn[i]) tarjan(i,,select);
if (bel[s]==bel[t]) return;
T.clear();
for (int i=;i<=n;i++)
for (int j=first[i];j;j=edge[j].next) if ((j>>)!=select)
{
const Edge &e=edge[j];
if (bel[i]!=bel[e.to]) T.in(bel[i],bel[e.to],e.v,j>>);
}
T.select=select; T.selectv=edge[select<<].v;
T.dfs(bel[s],,0x7fffffff,);
if (!T.ok) {if (edge[select<<].v<ans) {ans=edge[select<<].v; numofans=; whoisans[]=select;}}
} int main()
{
scanf("%d%d%d%d",&n,&m,&s,&t);
for (int i=,x,y,v;i<=m;i++) scanf("%d%d%d",&x,&y,&v),insert(x,y,v);
dfs(s);
if (ll==) {puts("0\n0"); return ;}
numofans=-; ans=0x7fffffff;
for (int i=;i<=ll;i++) tarjan(list[i]);
if (numofans==-) puts("-1");
else
{
printf("%d\n%d\n",ans,numofans);
for (int i=;i<=numofans;i++) printf("%d ",whoisans[i]);
}
return ;
}

Codeforces700C. Break Up的更多相关文章

  1. continue break 区别

    在循环中有两种循环方式 continue , break continue 只是跳出本次循环, 不在继续往下走, 还是开始下一次循环 break  将会跳出整个循环, 此循环将会被终止 count = ...

  2. C# 中Switch case 返回不止用break

    Switch(temp) { case "A": //跳出循环 break; case "B": //返回值 return var; case "C& ...

  3. jquery each函数 break和continue功能

    jquery each函数 break和continue功能幸运的是另一个突破,持续一个jQuery循环方式.你可以打破在函数返回一个jQuery参数虚假循环.一个可以继续执行只是在做不指定返回值或返 ...

  4. [LeetCode] Integer Break 整数拆分

    Given a positive integer n, break it into the sum of at least two positive integers and maximize the ...

  5. [LeetCode] Word Break II 拆分词句之二

    Given a string s and a dictionary of words dict, add spaces in s to construct a sentence where each ...

  6. R for循环之break,next

    next跳出本次循环 break跳出本层循环(当有多个for 循环时,即跳出最近的一个for循环)

  7. 关于break语句如何结束多重循环的嵌套

    在Java中的break语句功能大体上同c语言, 用于循环语句中,表示结束当前循环. 但是有时候在循环嵌套语句中,仅仅靠一 个break语句想实现是不够的. 例: 如果想使sum在501时就直接输出, ...

  8. break与continue的区别

    break       在while.for.do...while.while循环中使用break语句退出当前循环,直接执行后面的代码. continue   的作用是仅仅跳过本次循环,而整个循环体继 ...

  9. 高程(3):操作符、for、for...in循环、break/continue/return语句、函数等

    1.关系操作符 注意点:1)比较操作数是两个字符串,是比较字符串的字符编码值. 如:"a" > "b"  返回 false:"a" & ...

随机推荐

  1. 456 132 Pattern 132模式

    给定一个整数序列:a1, a2, ..., an,一个132模式的子序列 ai, aj, ak 被定义为:当 i < j < k 时,ai < ak < aj.设计一个算法,当 ...

  2. ssm(Spring、Springmvc、Mybatis)实战之淘淘商城-第五天(非原创)

    文章大纲 一.课程介绍二.前台系统(门户系统)搭建介绍三.前台系统(门户系统)搭建实战四.js请求跨域解决五.项目源码与资料下载六.参考文章   一.课程介绍 一共14天课程(1)第一天:电商行业的背 ...

  3. 萌新--关于vue.js入门及环境搭建

    十几天闭关修炼,恶补了html跟css以及JavaScript相应的基础知识,恰巧有个群友准备做开源项目,愿意带着我做,但是要求我必须懂vue.js,所以开始恶补vue.js相关的东西. 在淘宝上买了 ...

  4. VS2012创建WebForm项目提示错误: 此模板尝试加载组件程序集 “NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”。

    解决方案: 使用VS2012开发,都要装NuGet插件(官网:http://nuget.org),进官网点安装就进入了微软的下载页面, 选择vs2012版本的NuGet.Tools.vsix文件,双击 ...

  5. 机器学习-Probabilistic interpretation

    Probabilistic interpretation,概率解释  解释为何线性回归的损失函数会选择最小二乘 表示误差,表示unmodeled因素或随机噪声,真实的y和预测出来的值之间是会有误差的, ...

  6. oracle 时间格式转化以及计算

    --A表中的日期字段 create_date   例如:2017-08-05  转化为2017年8月5日   oracle 在这里的双引号会忽略 select to_char(to_date(tt.c ...

  7. hibernate cascade属性

    cascade属性是存在于set标签中,用来做级联删除和保存. 它的值有以下几种: 1)默认值是none,不做级联动作: 2)save-update:级联保存 3)delete:级联删除 4)all: ...

  8. Centos7 安装MongoDB的详细过程

    一.简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品 ...

  9. Hadoop推测执行机制问题

    问题描述:MultipleOutputs使用时hdfs报错         // :: INFO mapreduce.Job: Task Id : attempt_1525336138932_1106 ...

  10. flask中模板日期格式控制和jinja2中模板格式控制

    1.flask的模块语言采用的是jinja2,首先说一下jinja2中的模板格式控制的使用,即模板自定义filters的使用. python的脚本如下(采用的是格式显示日期): 1 from jinj ...