【tarjan缩点】hdu 3072

这题要先缩点在找没有入边的点,再找权值最小的边,注意:可能有重边,看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; }

 

你可能感兴趣的:(【tarjan缩点】hdu 3072)