学到了最小树形图这个东西 就是保留每个点所有入边中最小值 和无向图中的最小生成树类似
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define N 0x3f3f3f3f3f3f3f3f
struct node
{
int v;
ll w;
int next;
};
stack <int> stk;
node edge[100010];
ll minn[50010];
int first[50010],dfn[50010],low[50010],book[50010],belong[50010];
int n,m,num,cnt;
void addedge(int u,int v,ll w)
{
edge[num].v=v;
edge[num].w=w;
edge[num].next=first[u];
first[u]=num++;
return;
}
void dfs(int cur)
{
int i,v;
stk.push(cur);
dfn[cur]=num,low[cur]=num,book[cur]=1;
num++;
for(i=first[cur];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v])
{
dfs(v);
low[cur]=min(low[cur],low[v]);
}
else if(book[v])
{
low[cur]=min(low[cur],dfn[v]);
}
}
if(dfn[cur]==low[cur])
{
cnt++;
while(!stk.empty())
{
v=stk.top();
stk.pop();
book[v]=0;
belong[v]=cnt;
if(cur==v) break;
}
}
return;
}
void tarjan()
{
ll w;
int i,u,v;
while(!stk.empty()) stk.pop();
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(book,0,sizeof(book));
memset(belong,0,sizeof(belong));
num=1,cnt=0;
for(u=1;u<=n;u++)
{
if(!dfn[u]) dfs(u);
}
memset(minn,0x3f,sizeof(minn));
for(u=1;u<=n;u++)
{
for(i=first[u];i!=-1;i=edge[i].next)
{
v=edge[i].v,w=edge[i].w;
if(belong[u]!=belong[v])
{
minn[belong[v]]=min(minn[belong[v]],w);
}
}
}
return;
}
ll solve()
{
ll res,sum;
int i,j;
res=N;
for(i=1;i<=cnt;i++)
{
sum=0;
for(j=1;j<=cnt;j++)
{
if(i!=j)
{
sum+=minn[j];
}
}
res=min(res,sum);
}
return res;
}
int main()
{
int i,u,v,w;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(first,-1,sizeof(first));
num=0;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
u++,v++;
addedge(u,v,w);
}
tarjan();
if(cnt==1) printf("0\n");
else
{
printf("%lld\n",solve());
}
}
return 0;
}