原題連結
題解
原題可以理解為 \(\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;
}