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. [2020.03]Unity ML-Agents v0.15.0 环境部署与试运行

    一.ML-Agents简介 近期在学习Unity中的机器学习插件ML-Agents,做一些记录,用以简单记录或交流学习. 先简单说一下机器学习使用的环境场景:高视觉复杂度(Visual Complex ...

  2. JavaScript的函数(三)

    函数也是对象,拥有属性和方法,就类似普通对象那样.1,length属性 arguments.lenght 表示传入实参的个数. 函数的length属性时只读属性,代表形参的个数.可以用argument ...

  3. java 发送邮件详细讲解

    一.JavaMail概述:        JavaMail是由Sun定义的一套收发电子邮件的API,不同的厂商可以提供自己的实现类.但它并没有包含在JDK中,而是作为JavaEE的一部分. 厂商所提供 ...

  4. RIP实验

    实验要求 1.  理解 RIP 协议的工作原理2.  理解 RIPv1.RIPv2 的特性3.  掌握 RIP 协议的基本配置方法4.  掌握 RIP 自动汇总和手动汇总的方法5.  掌握 RIP 配 ...

  5. express模块中的req,res参数的常用属性方法

    express模块中的req,res参数的常用属性方法 const express = require('express'); const router = express.Router() rout ...

  6. npm 安装包总结

    1.前端可视化json:vue-json-viewer; 2.富文本编辑: vue-quill-editor;    https://www.cnblogs.com/ZaraNet/p/1020922 ...

  7. 9-4 Vue 缓存和子传副(组件)方法绑定

    学习了Vue框架近三个月,现在对数据绑定有了点认识,但是发现自己反而对js不是特别的熟. 下面是今天写代码刚好碰到的问题: 缓存的话:3句代码 sessionStorage.setItem(" ...

  8. git基础教程(八)

    8. gitlab相关介绍 8.1 gitlab优势 社区版本,自己可以在公司搭建环境 维护人员多,版本更新块 易用性强,上手快 集成CI(持续集成) 集成CD(持续发布) 8.2 持续集成 8.2. ...

  9. turtle学习笔记

    1.turtle的绘图窗体 turtle.setup(width, height, startx,starty) - setup()设置窗体大小及位置- 4个参数中后两个可选(后两个省略时默认窗口在屏 ...

  10. Python习题集(十三)

    每天一习题,提升Python不是问题!!有更简洁的写法请评论告知我! https://www.cnblogs.com/poloyy/category/1676599.html 题目 写一个函数,该函数 ...