E - E CodeForces - 1100E

一个n个节点的有向图,节点标号从1到n,存在m条单向边。每条单向边有一个权值,代表翻转其方向所需的代价。求使图变成无环图,其中翻转的最大边权值最小的方案,以及该方案翻转的最大的边权。

Input 单组输入,第一行包含两个整数n和m(2≤n≤100 000,1≤m≤100 000) 接下来m行,每行3个整数,u_i ,v_i

,w_i (1<= u_i , v_i <= n, 1<= w_i <=

10^9),表示u到v有一条权值为w的道路。道路编号从1开始。没有自环。

Output 在第一行中输出两个整数,即要翻转的最大的边权,和需要反转道路数量k。k不需要是最小的。

在下一行输出k个由空格分隔的整数,表示需要翻转的道路编号

如果有许多解决方案,请打印其中任何一个。

Examples
Input
5 6
2 1 1
5 2 6
2 3 2
3 4 3
4 5 5
1 5 4
Output
2 2
1 3
Input
5 7
2 1 5
3 2 3
1 3 3
2 4 1
4 3 5
5 4 1
1 5 3
Output
3 3
3 4 7

思路

  • 题意:给我一个有向带权值的图,这个图可能存在环,问所需改变的反转的边的最小权全是多少?
  • 思路:首先用二分枚举,要反转边的最大边权的最小值mid,都一个所给的图中的边中 边权小于mid 把这个边视为双向边(不存在),然后在剩下的子图中 跑一边 拓扑排序, 看是否有环的存在,如果有的话让 让 l = mid + 1, 否则 r = mid - 1
  • 链接



题解

#include<iostream>
#include<cmath>
#include<cstdio>
#include<queue>
#include<cstring>
#define int long long
#define inf 10000000000000
using namespace std;
int read(){
int res=0;char ch=0;
while (!isdigit(ch))ch=getchar();
while (isdigit(ch))res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
return res;
} const int N=1000100;
struct EDGE{
int ver,nxt,dis,pre;
}edge[N];
int n,m,cnt,head[N],vis[N],d[N],ans[N],dfn[N],dfs_cnt; void add(int u,int v,int t){
edge[++cnt].ver=v;
edge[cnt].nxt=head[u];
edge[cnt].dis=t;
edge[cnt].pre=u;
head[u]=cnt;
} queue<int>q;
bool check(int x){ memset(d,0,sizeof(d));memset(vis,0,sizeof(vis)); for (int i=1;i<=m;i++)if(edge[i].dis>x)d[edge[i].ver]++; for (int i=1;i<=n;i++)if (!d[i])q.push(i); while (!q.empty()){ int u=q.front();q.pop(); for (int i=head[u];i;i=edge[i].nxt)
{
if (edge[i].dis<=x)continue; int v=edge[i].ver;d[v]--;if (!d[v])q.push(v);
}
} for (int i=1;i<=n;i++)if (d[i])return 0; return 1;
}
void solute(int x){
memset(d,0,sizeof(d));memset(vis,0,sizeof(vis)); for (int i=1;i<=m;i++)if(edge[i].dis>x)d[edge[i].ver]++;
for (int i=1;i<=n;i++)if (!d[i])q.push(i); while (!q.empty())
{
int u=q.front();q.pop();dfn[u]=++dfs_cnt; for (int i=head[u];i;i=edge[i].nxt)
{
if (edge[i].dis<=x)continue;
int v=edge[i].ver;d[v]--;if (!d[v])q.push(v);
}
} for (int i=1;i<=m;i++){
if (edge[i].dis<=x){
int u=edge[i].pre,v = edge[i].ver;
if (dfn[u]>dfn[v])ans[++cnt]=i;
}
}
}
signed main(){
n=read();m=read();
for (int i=1;i<=m;i++){
int x=read(),y=read(),t=read();add(x,y,t);
}
int l=0,r=inf;
while (l<r)
{
int mid=l+r>>1;
if (check(mid))
r=mid;
else
l=mid+1;
} cnt=0;
solute(r);
printf("%lld %lld\n",r,cnt);
for (int i=1;i<=cnt;i++){
printf("%lld ",ans[i]);
}
}

E - E CodeForces - 1100E(拓扑排序 + 二分)的更多相关文章

  1. Codeforces 1100E 拓扑排序

    题意及思路:https://blog.csdn.net/mitsuha_/article/details/86482347 如果一条边(u, v),v的拓扑序小于u, 那么(u, v)会形成环,要反向 ...

  2. CROC 2016 - Elimination Round (Rated Unofficial Edition) D. Robot Rapping Results Report 拓扑排序+二分

    题目链接: http://www.codeforces.com/contest/655/problem/D 题意: 题目是要求前k个场次就能确定唯一的拓扑序,求满足条件的最小k. 题解: 二分k的取值 ...

  3. CF思维联系--CodeForces -214C (拓扑排序+思维+贪心)

    ACM思维题训练集合 Furik and Rubik love playing computer games. Furik has recently found a new game that gre ...

  4. CodeForces - 721C 拓扑排序+dp

    题意: n个点m条边的图,起点为1,终点为n,每一条单向边输入格式为: a,b,c     //从a点到b点耗时为c 题目问你最多从起点1到终点n能经过多少个不同的点,且总耗时小于等于t 题解: 这道 ...

  5. Codeforces 645D Robot Rapping Results Report【拓扑排序+二分】

    题目链接: http://codeforces.com/problemset/problem/645/D 题意: 给定n个机器人的m个能力大小关系,问你至少要前几个大小关系就可以得到所有机器人的能力顺 ...

  6. National Property CodeForces - 875C (拓扑排序)

    大意: n个字符串, 每次操作选出一种字符全修改为大写, 求判断能否使n个字符串字典序非降. 建源点s, 汇点t, s与所有必须转大写的连边, 必须不转大写的与t连边. #include <io ...

  7. Codeforces 1159E 拓扑排序

    题意及思路:https://www.cnblogs.com/dd-bond/p/10859864.html 代码: #include <bits/stdc++.h> #define LL ...

  8. CodeForces - 1100E 二分+拓扑排序

    题意: 一个n个节点的有向图,节点标号从1到n,存在m条单向边.每条单向边有一个权值,代表翻转其方向所需的代价.求使图变成无环图,其中翻转的最大边权值最小的方案,以及该方案翻转的最大的边权. Inpu ...

  9. codeforces 645 D. Robot Rapping Results Report 二分+拓扑排序

    题目链接 我们可以发现, 这是一个很明显的二分+拓扑排序.... 如何判断根据当前的点, 是否能构造出来一个唯一的拓扑序列呢. 如果有的点没有出现, 那么一定不满足. 如果在加进队列的时候, 同时加了 ...

随机推荐

  1. 峰哥说技术:03-Spring Boot常用注解解读

    Spring Boot深度课程系列 峰哥说技术—2020庚子年重磅推出.战胜病毒.我们在行动 03 Spring Boot常用注解解读 在Spring Boot中使用了大量的注解,我们下面对一些常用的 ...

  2. 1构建个人博客--使用Hugo快速成型

    概述 人在武汉,病毒肆虐. 隔离久了,有点闷,闲余时间找点事情做. 建个博客吧, 内容不重要,写不写也不那么要紧,目前水平也写不出什么有深度的东西. 但是这个姿势一定要优美, 过程一定要折腾. OK, ...

  3. Java自学路线图之Java系统自学

    Java自学不是一朝一夕的事情.可以采用"懒开始"的方法,但是必须要坚持下去,才能真正自学Java掌握编程技术.那些企图学几天去包装一下找工作的,请绕道.如果你下定决心自学Java ...

  4. 微博立场检测 60分Baseline

    AI研习社最近举办了一个比赛--微博立场检测,实际上就是一个NLP文本分类的比赛 Baseline-FastText 我的Baseline方法用的是pkuseg分词+FastText,最好成绩是60, ...

  5. js 面向对象 打气球小游戏

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. javaScript 基础知识汇总(八)

    1.Map Set WeakMap 和WeakSet Map 是一个键值对的集合,主要的方法包括: new Map() 创建Map map.set(key,value)  根据键(key)存储值(va ...

  7. java idea spring mvc 入门 最起码 我8080跑起来了

    IDEA建立Spring MVC Hello World 详细入门教程 https://www.cnblogs.com/wormday/p/8435617.html

  8. this.current = params.page || 1 (前提是params对象一定要存在)

    this.current = params.page || 1 (前提是params对象一定要存在)

  9. Java-正则表达式(新手)

    /* 正则表达式也是一个字符串,用来定义匹配规则,在Pattern类中有简单的规则定义.可以结合字符串类的方法使用. *///创建的一个类.public class LianxiFF1 { //公共静 ...

  10. JavaScript 模式》读书笔记(3)— 字面量和构造函数3

    这是字面量和构造函数的最后一篇内容,其中包括了JSON.正则表达式字面量,基本值类型包装器等知识点.也是十分重要的哦. 五.JSON JSON是指JavaScript对象表示以及数据传输格式.它是一种 ...