E. Andrew and Taxi
Andrew prefers taxi to other means of transport, but recently most taxi drivers have been acting inappropriately. In order to earn more money, taxi drivers started to drive in circles. Roads in Andrew's city are one-way, and people are not necessary able to travel from one part to another, but it pales in comparison to insidious taxi drivers.
The mayor of the city decided to change the direction of certain roads so that the taxi drivers wouldn't be able to increase the cost of the trip endlessly. More formally, if the taxi driver is on a certain crossroads, they wouldn't be able to reach it again if he performs a nonzero trip.
Traffic controllers are needed in order to change the direction the road goes. For every road it is known how many traffic controllers are needed to change the direction of the road to the opposite one. It is allowed to change the directions of roads one by one, meaning that each traffic controller can participate in reversing two or more roads.
You need to calculate the minimum number of traffic controllers that you need to hire to perform the task and the list of the roads that need to be reversed.
Input
The first line contains two integers nn and mm (2≤n≤1000002≤n≤100000, 1≤m≤1000001≤m≤100000) — the number of crossroads and the number of roads in the city, respectively.
Each of the following mm lines contain three integers uiui, vivi and cici (1≤ui,vi≤n1≤ui,vi≤n, 1≤ci≤1091≤ci≤109, ui≠viui≠vi) — the crossroads the road starts at, the crossroads the road ends at and the number of traffic controllers required to reverse this road.
Output
In the first line output two integers the minimal amount of traffic controllers required to complete the task and amount of roads kkwhich should be reversed. kk should not be minimized.
In the next line output kk integers separated by spaces — numbers of roads, the directions of which should be reversed. The roads are numerated from 11 in the order they are written in the input. If there are many solutions, print any of them.
Examples
input
Copy
5 6 2 1 1 5 2 6 2 3 2 3 4 3 4 5 5 1 5 4
output
Copy
2 2 1 3
input
Copy
5 7 2 1 5 3 2 3 1 3 3 2 4 1 4 3 5 5 4 1 1 5 3
output
Copy
3 3 3 4 7
Note
There are two simple cycles in the first example: 1→5→2→11→5→2→1 and 2→3→4→5→22→3→4→5→2. One traffic controller can only reverse the road 2→12→1 and he can't destroy the second cycle by himself. Two traffic controllers can reverse roads 2→12→1 and 2→32→3 which would satisfy the condition.
In the second example one traffic controller can't destroy the cycle 1→3→2→11→3→2→1. With the help of three controllers we can, for example, reverse roads 1→31→3 ,2→42→4, 1→51→5.
给你n个点,m条有向边,建图
问你可以翻转几条边使得这张图中没有环
要求反转的边最大的边尽可能地小
想到二分答案,二分翻转的最大边的权值
但是如果直接把所有小于等于答案的边翻转,可能会出现新的环
所以采用了拓扑排序的方法
只有每条边 起点的拓扑序 < 终点的拓扑序,这张图才是没有环的图
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
struct node
{
int u,v,w;
}a[maxn];
int n,m,in[maxn],top[maxn];
vector <int> e[maxn];
bool check(int mid)
{
int tot=0;
queue <int> q;
for(int i=1;i<=n;i++) e[i].clear(); //初始化
memset(in,0,sizeof(in));
for(int i=1;i<=m;i++)
{
if(a[i].w>mid) //需要保留的边建边
{
e[a[i].u].push_back(a[i].v);
in[a[i].v]++;
}
}
for(int i=1;i<=n;i++) //可以直接确定拓扑序的确定下来
{
if(!in[i])
{
q.push(i);
top[i]=++tot;
}
}
while(!q.empty()) //确定整张图的拓扑序
{
int t=q.front();
q.pop();
int sz=e[t].size();
for(int i=0;i<sz;i++)
{
int k=e[t][i];
in[k]--;
if(!in[k])
{
q.push(k);
top[k]=++tot;
}
}
}
for(int i=1;i<=n;i++) //要是还有边没扫完,就代表有环
{
if(in[i]) return 0;
}
return 1;
}
int main()
{
queue <int> que;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
}
int l=0,r=1e9,ans,mid,sum=0;
while(l<=r)
{
mid=(l+r)/2;
if(check(mid)) ans=mid,r=mid-1;
else l=mid+1;
}
check(ans);
for(int i=1;i<=m;i++)
{
if(a[i].w<=ans&&(top[a[i].u]>top[a[i].v])) //拓扑序被破坏了就说明错了
que.push(i),sum++;
}
printf("%d %d\n",ans,sum);
while(!que.empty())
{
printf("%d ",que.front());
que.pop();
}
return 0;
}