E - E CodeForces - 1100E (+ demi-tri topologique)

E - E CodeForces - 1100E

N a une noeuds de graphe orienté, les noeuds sont numérotés de 1 à n, m la présence de bords unidirectionnels. Chaque bord a un poids à sens unique, au nom du coût nécessaire pour inverser le sens de celui-ci. La figure cherche à faire en graphe acyclique, où les systèmes de pondération les plus petits flip bord au maximum, et le côté droit maximal du régime flip.

ensemble unique entrée des entrées, une première ligne contient deux entiers n et m (2≤n≤100 000,1≤m≤100 000) lignes suivantes m de trois nombres entiers, u_i, v_i
, W_i (. 1 <= u_i, v_i <= n- ,. 1 <= W_i <=
10 ^. 9), il y a un u à v représente un poids w à la route. Dès le début du numéro de la route 1. Non réalimentation.

Sortie Sortie deux nombres entiers dans la première ligne, qui est, à retourner à droite de la plus grande, et la nécessité d'inverser le nombre de route k. k ne doit pas être minime.

Sur la sortie de ligne suivante k-espace séparé nombre entier représentant le nombre de besoins de route pour inverser la

S'il existe de nombreuses solutions, imprimer un d'entre eux.

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 

pensée

  • Signification du titre: Donne-moi une carte à la valeur pondérée, ce chiffre peut exister anneau, tandis que l'inversion de poids minimum demander combien est nécessaire de changer l'ensemble?
  • Idée: d'abord avec l'énumération binaire, la partie maximale sur le côté droit du minimum inverseuse milieu, sont donnés un dessin du bord latéral droit de l'arête est inférieure à la moitié considérée bord bidirectionnel (non présent), puis le reste enfant figure sous le côté courant tri topologique, pour voir s'il y a anneau, le cas échéant, laissez l = milieu + 1, sinon r = mi - 1
  • lien

problème solution

#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]);
    }
}

Je suppose que tu aimes

Origine www.cnblogs.com/lql-nyist/p/12629446.html
conseillé
Classement