F. Microcycle

纯粹的發表於2024-03-12

原題連結

題解

原題可以理解為 \(\to\) 找出含有最小邊權的邊雙連通分量,然後找出那個邊對應的兩個節點的第二條路

本題我學會了:
1.程式碼命名風格要含義清晰,不然很容易搞混,包括變數,自定義函式
2.建邊的時候儘量用連結串列式,因為dalao都在用,看題解方便一點

code


#define ll long long
#include<bits/stdc++.h>
using namespace std;
ll depth=0;
stack<ll> q;
ll dfn[200010]={0},low[200010]={0};
ll cnt=0;
ll belong[200010]={0};
ll last[400010]={0};
struct node
{
    int from,to,val,head;
}edge[400010];
void add(int from,int to,int val,int num)
{
    edge[num].to=to;
    edge[num].from=from;
    edge[num].val=val;
    edge[num].head=last[from];
    last[from]=num;
}

inline void read(ll &x) {
    x = 0;
    ll flag = 1;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-')flag = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') {
        x = (x << 3) + (x << 1) + (c ^ 48);
        c = getchar();
    }
    x *= flag;
}

inline void write(ll x)
{
    if(x < 0){
        putchar('-');
        x = -x;
    }
    if(x > 9)
        write(x / 10);
    putchar(x % 10 + '0');
}


void flss(ll now,ll fa)
{
    dfn[now]=low[now]=++depth;

    q.push(now);
    for(int i=last[now];i;i=edge[i].head)
    {
        ll to=edge[i].to;
        if(to==fa) continue;
        if(!dfn[to])
        {
            flss(to,now);
            low[now]=min(low[now],low[to]);
        }
        else low[now]=min(low[now],dfn[to]);
    }

    if(low[now]==dfn[now])
    {
        cnt++;
        ll x;
        do
        {
            x=q.top();
            q.pop();
            belong[x]=cnt;
        }while(x!=now);
    }
}


stack<int> st;
int vis[200005]={0};
int dfs(ll now,ll fa,ll ends)
{
    st.push(now);
    vis[now]=1;

    if(now==ends)
    {
        cout<<st.size()<<endl;
        while(st.size())
        {
            cout<<st.top()<<" ";
            vis[st.top()]=0;
            st.pop();
        }

        puts("");
        return 1;
    }

    for(int i=last[now];i;i=edge[i].head)
    {
        ll to=edge[i].to,val=edge[i].val;
        if(to==fa||vis[to]||belong[to]!=belong[now]) continue;
        if (dfs(to,now,ends)) return 1;
    }
    st.pop();
    //vis[now]=0;導致我#19TLE的罪魁禍首
    return 0;
}


int main()
{
    ll t;
    read(t);
    while(t--)
    {
        ll n,m;
        read(n); read(m);
        for(ll i=1;i<=n;i++)
        {
            dfn[i]=0;
            low[i]=0;
            last[i]=0;
            vis[i]=0;
            belong[i]=0;
        }
        cnt=0;
        depth=0;
        for(ll i=1;i<=m;i++)
        {
            ll x,y,w;
            read(x); read(y); read(w);
            add(x,y,w,i);
            add(y,x,w,i+m);
        }

        for(ll i=1;i<=n;i++) if(!dfn[i]) flss(i,i);
        ll ans=2e17;
        for(ll i=1;i<=m;i++)
        {
            ll x=edge[i].from,y=edge[i].to,val=edge[i].val;
            if(belong[x]==belong[y]) ans=min(ans,val);
        }

        write(ans); putchar(' ');
        for(ll i=1;i<=m;i++)
        {
            ll x=edge[i].from,y=edge[i].to,val=edge[i].val;
            if(belong[x]==belong[y]&&val==ans)
            {
                dfs(x,y,y);
                break;
            }
        }
    }
    return 0;
}