这题要先缩点在找没有入边的点,再找权值最小的边,注意:可能有重边,看sample3就知道!
用vector和stack的缘故,比较慢500+ms
#include <list>
#include <map>
#include <set>
#include <queue>
#include <string>
#include <deque>
#include <stack>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <math.h>
#include <cstdlib>
#include <limits.h>
#include <time.h>
#include <string.h>
using namespace std;
#define LL long long
#define PI acos(-1.0)
#define FRE freopen("a.txt","r",stdin)
#define MAX INT_MAX
#define MIN INT_MIN
#define eps 1e-10
#define MOD 1000000007
#define N 50005
int min(int a,int b){return a<b?a:b;}
struct node{
int t;
int w;
};
int n,m;
vector<node> v[N];
stack<int> s;
bool vis[N];
bool Instack[N];
int low[N],dfn[N];
int belong[N];
int step,t;
int cost[N];
void init(){
int i;
for(i=0;i<=n;i++){
v[i].clear();
vis[i]=0;
low[i]=dfn[i]=0;
Instack[i]=0;
belong[i]=0;
cost[i]=MAX;
}
while(!s.empty())s.pop();
t=0;
step=0;
}
void tarjan(int u){
vis[u]=1;
step++;
s.push(u);
Instack[u]=1;
low[u]=dfn[u]=step;
int i,j;
for(i=0;i<v[u].size();i++){
int x=v[u][i].t;
if(!vis[x]){
tarjan(x);
low[u]=min(low[u],low[x]);
}
else{
if(Instack[x])
low[u]=min(low[u],dfn[x]);
}
}
if(low[u]==dfn[u]){
t++;
while(1){
int x=s.top();
s.pop();
belong[x]=t; ////
Instack[x]=0;
if(x==u)break;
}
}
}
void gao(){
int i,j;
for(i=0;i<n;i++)
if(!vis[i])
tarjan(i);
for(i=0;i<n;i++){
int x=belong[i];
for(j=0;j<v[i].size();j++){
int y=belong[v[i][j].t];
if(x==y)continue;
else{
cost[y]=min(cost[y],v[i][j].w);
}
}
}
int ans=0;
for(i=0;i<n;i++){
if(cost[i]!=MAX)
ans+=cost[i];
}
printf("%d\n",ans);
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
int i,j;
init();
while(m--){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
node tmp;
tmp.t=b;
tmp.w=c;
v[a].push_back(tmp);
}
gao();
}
return 0;
}