hdu1269迷宫城堡 hdu 1827Summer Holiday

这两题都是强连通。。

上午刚开过,下午放学后就趁热打铁,把这两道题也给解决了。。。

只要把kosaraju的意思理解了,用起来会很顺手的,,对于这一类的题目只需要稍微改下就可以了。。

对于1269题,很明显强连通,,只需要判断Bcnt就行了,判断有多少了强连通分支。。。

1827题,Wiskey只需要和 入度为0的强连通分支打电话。。。

对于这样的强连通分支找到打电话所耗的费用最少的一个,,可以在第二个dfs里面处理一下就行了,记录耗用电话费最少的。。。

1269题就不贴代码了,,

1827代码:

View Code
 1 # include<stdio.h>

 2 # include<string.h>

 3 # define N 1005

 4 # define M 2005

 5 struct node{

 6     int from,to,next;

 7 }edge1[M],edge2[M];

 8 int visit1[N],visit2[N],head1[N],head2[N],T[N];

 9 int in_degree[N],out_degree[N],tol1,tol2,Bcnt,Tcnt;

10 int val[N],v1[N],min,Belong[N];

11 void add(int a,int b)

12 {

13     edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];head1[a]=tol1++;

14     edge2[tol2].from=b;edge2[tol2].to=a;edge2[tol2].next=head2[b];head2[b]=tol2++;

15 }

16 void dfs1(int x)

17 {

18     int i;

19     visit1[x]=1;

20     for(i=head1[x];i!=-1;i=edge1[i].next)

21         if(visit1[edge1[i].to]==0) dfs1(edge1[i].to);

22     T[Tcnt++]=x;

23 }

24 void dfs2(int x)

25 {

26     int i;

27     Belong[x]=Bcnt;

28     if(val[x]<min) min=val[x];

29     visit2[x]=1;

30     for(i=head2[x];i!=-1;i=edge2[i].next)

31         if(visit2[edge2[i].to]==0) dfs2(edge2[i].to);

32 }

33 int main()

34 {

35     int i,n,m,sum,x,y,a,b,count;

36     while(scanf("%d%d",&n,&m)!=EOF)

37     {

38         tol1=tol2=0;

39         Bcnt=Tcnt=0;

40         for(i=1;i<=n;i++)

41         {

42             head1[i]=-1;

43             head2[i]=-1;

44             visit1[i]=0;

45             visit2[i]=0;

46             scanf("%d",&val[i]);

47         }

48         while(m--)

49         {

50             scanf("%d%d",&a,&b);

51             add(a,b);

52         }

53         for(i=1;i<=n;i++) 

54             if(visit1[i]==0) dfs1(i);

55         for(i=Tcnt-1;i>=0;i--)

56         {

57             if(visit2[T[i]]==0)

58             {

59                 min=0xfffffff;

60                 dfs2(T[i]);

61                 v1[Bcnt]=min;

62                 Bcnt++;

63             }

64         }

65         for(i=0;i<Bcnt;i++)

66         {

67             in_degree[i]=0;

68             out_degree[i]=0;

69         }

70         for(i=0;i<tol1;i++)

71         {

72             x=Belong[edge1[i].from];

73             y=Belong[edge1[i].to];

74             if(x!=y)

75             {

76                 in_degree[y]=1;

77                 out_degree[x]=1;

78             }

79         }

80         sum=0;

81         count=0;

82         for(i=0;i<Bcnt;i++)

83         {

84             if(in_degree[i]==0)  {sum+=v1[i];count++;}

85         }

86         printf("%d %d\n",count,sum);

87     }

88     return 0;

89 }

 

 

 顺便再贴一个刚 学的tarjan的模版,代码很丑陋!!

1827:

View Code
 1 # include<stdio.h>
2 # include<string.h>
3 # include<stack>
4 usingnamespace std;
5 # define N 1005
6 # define M 2005
7 struct node{
8 int from,to,next;
9 }edge[M];
10 int head[N],tol,vis[N],n,m,cnt,visit[N],dfn[N],low[N],count,Belong[N],sum,val[N],val1[N],count1,degree[N];
11 stack<int>Stack;
12 void add(int a,int b)
13 {
14 edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];head[a]=tol++;
15 }
16 int min(int a,int b)
17 {
18 return a<b?a:b;
19 }
20 void tarjan(int u)
21 {
22 int j,v,Min;
23 dfn[u]=low[u]=cnt++;
24 Stack.push(u);
25 visit[u]=vis[u]=1;
26 for(j=head[u];j!=-1;j=edge[j].next)
27 {
28 v=edge[j].to;
29 if(!visit[v])//
30 {
31 tarjan(v);
32 low[u]=min(low[v],low[u]);
33 }
34 elseif(vis[v])//
35 low[u]=min(low[u],dfn[v]);
36 }
37 if(dfn[u]==low[u])
38 {
39 count++;
40 Min=val[u];
41 do{
42 v=Stack.top();
43 Stack.pop();
44 vis[v]=0;
45 Min=min(Min,val[v]);
46 Belong[v]=count;
47 }while(v!=u);
48 val1[count]=Min;
49 }
50 }
51 int main()
52 {
53 int i,a,b,j,u;
54 while(scanf("%d%d",&n,&m)!=EOF)
55 {
56 //if(n==0 && m==0) break;
57 for(i=1;i<=n;i++)
58 scanf("%d",&val[i]);
59 memset(head,-1,sizeof(head));
60 tol=0;
61 cnt=0;
62 for(i=1;i<=m;i++)
63 {
64 scanf("%d%d",&a,&b);
65 add(a,b);
66 }
67 memset(vis,0,sizeof(vis));
68 memset(visit,0,sizeof(visit));
69 sum=0;//表示需要的最少话费
70 count=0;//表示强联通分量的个数
71 for(i=1;i<=n;i++)
72 if(!visit[i]) tarjan(i);
73 //if(count==1) printf("Yes\n");
74 //else printf("No\n");
75 memset(degree,0,sizeof(degree));
76 for(i=1;i<=n;i++)
77 {
78 for(j=head[i];j!=-1;j=edge[j].next)
79 {
80 u=edge[j].to;
81 if(Belong[i]==Belong[u]) continue;
82 degree[Belong[u]]++;
83 }
84 }
85 count1=0;
86 for(i=1;i<=count;i++)
87 {
88 if(!degree[i]) {sum+=val1[i];count1++;}
89 }
90 //for(i=1;i<=n;i++)
91 //printf("%d:%d\n",i,Belong[i]);
92 printf("%d %d\n",count1,sum);
93 }
94 return0;
95 }

你可能感兴趣的:(HDU)