强连通 HDU 1827

n个点m条边

n个权lcy 要叫这个人的花费

m条边

缩点后 新的图中 入度为0的点要通知  通知强连通分量中权值最小的

  1 #include<stdio.h>
  2 #include<algorithm>
  3 #include<string.h>
  4 #include<queue>
  5 #include<math.h>
  6 #include<stack>
  7 
  8 using namespace std;
  9 
 10 #define MAXN 100010
 11 #define inf  100000000
 12 int head[MAXN],low[MAXN],dfn[MAXN],f[MAXN],in[MAXN],out[MAXN],z[MAXN];
 13 bool vis[MAXN];
 14 int cnt,k,num;
 15 struct edg
 16 {
 17     int fr,to,next;
 18 
 19 }x[MAXN];
 20 
 21 void add(int u,int v)
 22 {
 23     x[cnt].next=head[u];
 24     x[cnt].fr=u;
 25     x[cnt].to=v;
 26     head[u]=cnt++;
 27 }
 28 stack<int>s;
 29 
 30 void dfs(int u)
 31 {
 32     low[u]=dfn[u]=k++;
 33     vis[u]=1;
 34     s.push(u);
 35     int i;
 36     for(i=head[u];i!=-1;i=x[i].next)
 37     {
 38         int t=x[i].to;
 39         if(!dfn[t])
 40         {
 41             dfs(t);
 42             low[u]=min(low[u],low[t]);
 43         }
 44         else if(vis[t])
 45             low[u]=min(low[u],dfn[t]);
 46     }
 47     if(low[u]==dfn[u])
 48     {
 49         num++;
 50         while(!s.empty())
 51         {
 52             int now=s.top();
 53             s.pop();
 54             vis[now]=0;
 55             f[now]=num;
 56             if(now==u)break;
 57         }
 58     }
 59 }
 60 
 61 int main()
 62 {
 63     int n,m,t;
 64 
 65     while(scanf("%d%d",&n,&m)!=EOF)
 66     {
 67         int i,j;
 68         for(i=1;i<=n;i++)
 69             scanf("%d",&z[i]);
 70         memset(head,-1,sizeof(head));
 71         cnt=0;
 72         for(i=1;i<=m;i++)
 73         {
 74             int a,b;
 75             scanf("%d%d",&a,&b);
 76             add(a,b);
 77         }
 78         k=1;
 79         num=0;
 80         memset(dfn,0,sizeof(dfn));
 81         memset(low,0,sizeof(low));
 82         memset(vis,0,sizeof(vis));
 83         memset(f,0,sizeof(f));
 84         for(i=1;i<=n;i++)
 85         {
 86             if(!dfn[i])
 87                 dfs(i);
 88         }
 89         memset(head,-1,sizeof(head));
 90         int en=cnt;
 91         memset(in,0,sizeof(in));
 92 
 93         for(i=0;i<en;i++)
 94         {
 95             int u,v;
 96             u=f[x[i].fr];
 97             v=f[x[i].to];
 98             if(u!=v)
 99             {
100                 add(u,v);
101                 in[v]++;
102             }
103         }
104         int ans=0,ans1=0;
105 
106         for(i=1;i<=num;i++)
107         {
108             if(in[i]==0)
109             {
110                 ans1++;
111                 int m1=inf;
112                 for(j=1;j<=n;j++)
113                 {
114                     if(f[j]==i)
115                         m1=min(m1,z[j]);
116                 }
117                 ans=ans+m1;
118             }
119         }
120         printf("%d %d
",ans1,ans);
121     }
122     return 0;
123 }

ans+=w, num++

原文地址:https://www.cnblogs.com/cherryMJY/p/6058853.html