1002 图论专练 解题报告

T1  重量不同的硬币

有N(1 <= N <= 1,000)个硬币,编号为1..N。

给出W(1 <= W <= 3,000)个推断对(A,B),表示硬币A比硬币B重。

寻找并输出一个硬币编号,要求其重量明确不同于其他硬币的个数最多。如果有多个答案,输出编号最小的一个。如果给出的数据有矛盾,输出"IMPOSSIBLE"

PROBLEM NAME: coins

INPUT FORMAT:

* Line 1: 两个整数: N and W.

* Lines 2..W+1: 每行两个整数: A, B

OUTPUT FORMAT:

* Line 1: 重量不同于其他硬币的个数最多的硬币编号。

【题解】

根据题意建图,注意正反图都要建(蒟蒻考试时没有建反图,挂掉)

如果图中有环,显然是"IMPOSSIBLE",所以先用tarjan判环。

然后两遍dfs遍历,找到每个结点的子树大小,输出最大的编号就行了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<ctime>
 7 #include<algorithm>
 8 #include<queue>
 9 using namespace std;
10 #define INF 1000000000
11 #define MAXN 3010
12 struct node{int y,next,v;}e[MAXN*2];
13 int n,m,len,ans,now,bcnt,top,maxx,Link[MAXN],stack[MAXN],inst[MAXN],vis[MAXN],dfn[MAXN],low[MAXN],belong[MAXN],cnt1[MAXN],cnt2[MAXN];
14 inline int read()
15 {
16     int x=0,f=1;  char ch=getchar();
17     while(!isdigit(ch))  {if(ch==‘-‘)  f=-1;  ch=getchar();}
18     while(isdigit(ch))  {x=x*10+ch-‘0‘;  ch=getchar();}
19     return x*f;
20 }
21 void insert(int x,int y,int v)
22 {
23     e[++len].next=Link[x];
24     Link[x]=len;
25     e[len].y=y;
26     e[len].v=v;
27 }
28 void tarjan(int x)
29 {
30     dfn[x]=low[x]=++now;
31     stack[++top]=x;  inst[x]=1;
32     for(int i=Link[x];i;i=e[i].next)
33         if(e[i].v)
34         {
35             if(!dfn[e[i].y])
36             {
37                 tarjan(e[i].y);
38                 low[x]=min(low[x],low[e[i].y]);
39             }
40             else if(inst[e[i].y]) low[x]=min(low[x],dfn[e[i].y]);
41         }
42     if(dfn[x]==low[x])
43     {
44         int y;  bcnt++;
45         do
46         {
47             y=stack[top--];
48             inst[y]=0;
49             belong[y]=bcnt;
50         }while(y!=x);
51     }
52 }
53 void dfs1(int x)
54 {
55     cnt1[x]=1;  vis[x]=1;
56     for(int i=Link[x];i;i=e[i].next)
57         if(!vis[e[i].y]&&e[i].v)
58         {
59             dfs1(e[i].y);
60             cnt1[x]+=cnt1[e[i].y];
61         }
62 }
63 void dfs2(int x)
64 {
65     cnt2[x]=1;  vis[x]=1;
66     for(int i=Link[x];i;i=e[i].next)
67         if(!vis[e[i].y]&&!e[i].v)
68         {
69             dfs2(e[i].y);
70             cnt2[x]+=cnt2[e[i].y];
71         }
72 }
73 int main()
74 {
75     freopen("coins.in","r",stdin);
76     freopen("coins.out","w",stdout);
77     n=read();  m=read();
78     for(int i=1;i<=m;i++)
79     {
80         int x=read(),y=read();
81         insert(x,y,1);  insert(y,x,0);
82     }
83     for(int i=1;i<=n;i++)  if(!dfn[i])  tarjan(i);
84     for(int i=1;i<=n;i++)
85     {
86         if(vis[belong[i]])  {printf("IMPOSSIBLE\n");  return 0;}
87         else vis[belong[i]]=1;
88     }
89     for(int i=1;i<=n;i++)
90     {
91         memset(vis,0,sizeof(vis));
92         dfs1(i);
93         memset(vis,0,sizeof(vis));
94         dfs2(i);
95         if(cnt1[i]+cnt2[i]>maxx)  {maxx=cnt1[i]+cnt2[i];  ans=i;}
96     }
97     printf("%d\n",ans);
98     return 0;
99 }

T2  杀人游戏

【问题描述】

天黑请闭眼……

杀人游戏其实小x并不会玩,于是他自己设计了一个杀人游戏。

现在有n个人,每个人都有一个自己要杀的对象,并且轮到他后,他肯定可以杀掉自己想杀的人,当然,如果有人想自杀,轮到自己的时候,也是可以杀掉自己的。

现在,作为游戏的主宰,你可以设计杀人的顺序,顺序不一样,死的人的数目肯定也不一样。现在你想知道,如何设计顺序,让死的最多和最少。

【输入】

第一行,一个整数n,表示有n个人。

第二行,n个用空格隔开整数Xi,Xi表示第i个人要杀的人的编号。

【输出】

空格隔开的两个整数,minn和maxx,表示最少的杀人数和最多的杀人数。

【题解】

问题1,最少死几个人:

没有入度的点必然不死,不死的点指向的点必死。使用拓扑排序实现,若最后剩下环且环上所有点都不死,则每个环死亡人数为(L+1)/2。

问题2,最多死几个人:

没有入度的点必然不死,若存在没有叶子且长度大于1的环,则该环上有一个人不死。其余人都可以死亡。

【吐槽】

考试时策略想错了,搞了2个多小时的平衡树,只得了10分。。。

这启示这我们没事别瞎搞高级数据结构。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<ctime>
 7 #include<algorithm>
 8 using namespace std;
 9 #define MAXN 1000010
10 int n,head,tail,ans1,ans2,a[MAXN],id[MAXN],q[MAXN],die[MAXN],undie[MAXN];
11 inline int read()
12 {
13     int x=0,f=1;  char ch=getchar();
14     while(!isdigit(ch))  {if(ch==‘-‘)  f=-1;  ch=getchar();}
15     while(isdigit(ch))  {x=x*10+ch-‘0‘;  ch=getchar();}
16     return x*f;
17 }
18 int main()
19 {
20     freopen("maf.in","r",stdin);
21     freopen("maf.out","w",stdout);
22     n=read();
23     for(int i=1;i<=n;i++)  {a[i]=read();  id[a[i]]++;}
24     for(int i=1;i<=n;i++)  if(!id[i])  q[++tail]=i;  ans1=tail;
25     while(++head<=tail)
26     {
27         int x=q[head];  ans2=tail;
28         if(die[a[x]])  continue;
29         die[a[x]]=1;  undie[a[a[x]]]=1;
30         if(--id[a[a[x]]]==0)  q[++tail]=a[a[x]];
31     }
32     for(int i=1;i<=n;i++)
33         if(id[i]&&!die[i])
34         {
35             int len=0,flag=0;
36             for(int j=i;!die[j];j=a[j])
37             {
38                 die[j]=1;  len++;
39                 flag|=undie[j];
40             }
41             if(!flag&&len>1)  ans1++;
42             ans2+=len/2;
43         }
44     printf("%d %d",n-ans2,n-ans1);
45     return 0;
46 }

T3  board

你在玩一个棋盘游戏. 给出一个R ×  C 的棋盘. 棋盘的每个格子雕刻了一个0到9的数字,或障碍物(用H表示).你的任务是从左上角开始走,最多能走多少步.  每一步的走法是这样的:

(1)查看你现在所处的格子,看它雕刻的数字,设为x.

(2)你可以选择四个方向走: 上、下、左、右.

(3)在你选择的方向跨x步(中间可以有障碍物)。

例如,棋盘用b[R][C]表示,b[1][1] = 3, 而你此刻就在第一行第一列,你决定向右走,那么你将到达第一行第四列。

当你跳进了一个障碍物格子,或者跳出界了,那么游戏结束.

输入:

第一行 : R 和 C, 表示棋盘的行数和列数.  1 <= R , C <=50

接下来有R行,每行C个字符,每个字符要么是0-9的数字,要么是字符H.

输出:

从左上角开始走,你最多能走多少步. 如果可以走无穷步,输出-1

【题解】

首先建图:每一个点设置一个编号,终点设为n*m+1,每个点先它能到达的点连一条边。

然后tarjan判环:如果图中有环,显然应该输出-1.

最后在图上跑最长路,dis值最大的就是答案。

【吐槽】

考试时没有判环,而且写了一个带回溯的dfs,成功挂掉。

昨天改了一下午,一直是秘制错误,蒙大神Cydiater指点,原来是数组开小了。。。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<ctime>
  7 #include<algorithm>
  8 #include<queue>
  9 using namespace std;
 10 #define INF 1000000000
 11 #define MAXN 1000000
 12 const int dx[4]={1,0,-1,0};
 13 const int dy[4]={0,-1,0,1};
 14 struct node{int y,next,v;}e[MAXN];
 15 int n,m,len,ans,top,cnt,flag,now,bcnt,node[55][55],belong[MAXN],dis[MAXN],Link[MAXN],q[MAXN],vis[MAXN],dfn[MAXN],low[MAXN],stack[MAXN],instack[MAXN];
 16 char map[55][55];
 17 inline int read()
 18 {
 19     int x=0,f=1;  char ch=getchar();
 20     while(!isdigit(ch))  {if(ch==‘-‘)  f=-1;  ch=getchar();}
 21     while(isdigit(ch))  {x=x*10+ch-‘0‘;  ch=getchar();}
 22     return x*f;
 23 }
 24 void insert(int x,int y,int v)
 25 {
 26     e[++len].next=Link[x];
 27     Link[x]=len;
 28     e[len].y=y;
 29     e[len].v=v;
 30 }
 31 int cal(int a,int b)
 32 {
 33     if(a<1||b<1||a>n||b>m)  return n*m+1;
 34     if(map[a][b]==‘H‘)  return n*m+1;
 35     return (a-1)*m+b;
 36 }
 37 void tarjan(int x)
 38 {
 39     dfn[x]=low[x]=++now;
 40     stack[++top]=x;  instack[x]=1;
 41     for(int i=Link[x];i;i=e[i].next)
 42     {
 43         if(!dfn[e[i].y])
 44         {
 45             tarjan(e[i].y);
 46             low[x]=min(low[x],low[e[i].y]);
 47         }
 48         else if(instack[e[i].y])  low[x]=min(low[x],dfn[e[i].y]);
 49     }
 50     if(dfn[x]==low[x])
 51     {
 52         int y;  bcnt++;
 53         do
 54         {
 55             y=stack[top--];
 56             instack[y]=0;
 57             belong[y]=bcnt;
 58         }while(x!=y);
 59     }
 60 }
 61 void spfa()
 62 {
 63     memset(vis,0,sizeof(vis));
 64     memset(dis,0,sizeof(dis));
 65     int head=0,tail=1;
 66     q[1]=1;  vis[1]=1;  dis[1]=0;
 67     while(++head<=tail)
 68     {
 69         int x=q[head];
 70         for(int i=Link[x];i;i=e[i].next)
 71         {
 72             if(dis[x]+e[i].v>dis[e[i].y])
 73             {
 74                 dis[e[i].y]=dis[x]+e[i].v;
 75                 if(!vis[e[i].y])
 76                 {
 77                     vis[e[i].y]=1;
 78                     q[++tail]=e[i].y;
 79                 }
 80             }
 81         }
 82         vis[x]=0;
 83     }
 84 }
 85
 86 int main()
 87 {
 88     freopen("board.in","r",stdin);
 89     freopen("board.out","w",stdout);
 90     n=read();  m=read();
 91     for(int i=1;i<=n;i++)
 92     {
 93         scanf("\n");
 94         for(int j=1;j<=m;j++)
 95             scanf("%c",&map[i][j]);
 96     }
 97     for(int i=1;i<=n;i++)
 98         for(int j=1;j<=m;j++)
 99             if(map[i][j]!=‘H‘)
100             {
101                 int p=map[i][j]-‘0‘,x=cal(i,j),y=0;
102                 y=cal(i+p,j);  insert(x,y,1);
103                 y=cal(i-p,j);  insert(x,y,1);
104                 y=cal(i,j+p);  insert(x,y,1);
105                 y=cal(i,j-p);  insert(x,y,1);
106             }
107     for(int i=1;i<=n*m+1;i++)  if(!dfn[i])  tarjan(i);
108     for(int i=1;i<=n*m+1;i++)
109     {
110         if(vis[belong[i]])  {printf("-1\n");  return 0;}
111         else vis[belong[i]]=1;
112     }
113     spfa();
114     for(int i=1;i<=n*m+1;i++)  ans=max(ans,dis[i]);
115     printf("%d\n",ans);
116     return 0;
117 }

T4  魔法逮鱼

【问题描述】

Jzyz的人工湖里有很多很多鱼,小x发现,在湖底有n个坑,到每条鱼会找一个坑进行休息,如果一个坑被一条鱼占据,就不会有其他鱼来休息。当然,不一定每一个坑都有鱼。

现在小x会一种魔法,可以判断出从连续的坑里的鱼的个数是奇数还是偶数。当然,魔法必须要消耗魔力,如果判断一次从第i个坑到底j个坑的鱼的情况,小x需要话费Cij的魔力。

现在问题来了,小x想知道,最少需要话费多少魔力,才能知道每个坑里是否有鱼。

【输入】

第一行,一个整数n

接下来n行,第i行有n-i+1个整数,表示一次询问话费的魔力,其中Cij为第i行第j-i列个数 (1<=i<=j<=n,1<=c_ij<=10^9)

【输出】

一个整数,表示最小的魔力话费。

【题解】

一个神奇的最小生成树问题。

我就不再写题解了,详见:http://www.cnblogs.com/zrts/p/bzoj3714.html

【吐槽】

考试时并查集写错了,无限想抽自己。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<ctime>
 7 #include<algorithm>
 8 #include<queue>
 9 using namespace std;
10 #define INF 1000000000
11 #define MAXN 4000010
12 struct node{int x,y,v;}e[MAXN];
13 int n,len,k,f[MAXN];
14 long long ans;
15 inline int read()
16 {
17     int x=0,f=1;  char ch=getchar();
18     while(!isdigit(ch))  {if(ch==‘-‘)  f=-1;  ch=getchar();}
19     while(isdigit(ch))  {x=x*10+ch-‘0‘;  ch=getchar();}
20     return x*f;
21 }
22 bool mycmp(node a,node b) {return a.v<b.v;}
23 void insert(int x,int y,int v)  {e[++len].x=x;e[len].y=y;e[len].v=v;}
24 int find(int x)  {return f[x]==x?x:f[x]=find(f[x]);}
25 int main()
26 {
27     freopen("kug.in","r",stdin);
28     freopen("kug.out","w",stdout);
29     n=read();
30     for(int i=1;i<=n;i++)
31         for(int j=i;j<=n;j++)
32         {
33             int v=read();
34             insert(i,j+1,v);
35         }
36     sort(e+1,e+len+1,mycmp);
37     for(int i=1;i<=n;i++)  f[i]=i;
38     for(int i=1;i<=len;i++)
39     {
40         int x=find(e[i].x),y=find(e[i].y);
41         if(x!=y)
42         {
43             f[x]=y;
44             ans+=e[i].v;
45         }
46     }
47     printf("%I64d\n",ans);
48     return 0;
49 }

T5  这题有点玄学,先留个坑。

T6  黑暗城堡(castle.pas/c/cpp)

题目描述

在顺利攻破 Lord lsp 的防线之后,lqr 一行人来到了 Lord lsp 的城堡下方。Lord lsp 黑化 之后虽然拥有了强大的超能力,能够用意念力制造建筑物,但是智商水平却没怎么增加。现 在 lqr 已经搞清楚黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度。

lqr 深知 Lord lsp 的想法, 为了避免每次都要琢磨两个 房间之间的最短路径,Lord lsp 一定会把城堡修建成树形的; 但是,为了尽量提高自己的移 动效率,Lord  lsp 一定会使得 城堡满足下面的条件:设 Di 为如果所有的通道都被修建, 第 i 号房间与第 1 号房间的最 短路径长度;而 Si 为实际修建 的树形城堡中第 i 号房间与第1 号房间的路径长度,对于所有满足 1≤i≤N 的整数 i,有 Si  = Di。

为了打败 Lord lsp,lqr 想知道有多少种不同的城堡修建方案。于是 lqr 向 applepi 提出了这个问题。由于 applepi 还 要忙着出模拟赛,所以这个任务就交给你了。当然,你只需要输出答案对 231  – 1 取模之后 的结果就行了。

输入格式

第一行有两个整数 N 和 M。

之后 M 行,每行三个整数 X,Y 和 L,表示可以修建 X 和 Y 之间的一条长度为 L 的通

道。

输出格式

输出一个整数,表示答案对 231 – 1 取模之后的结果。

【题解】

======================题解来自mzx============================

很显然题目要求的是一个图的生成树,这棵生成树要求满足根节点到每个结点的距离都等于原图中的最短距离

我们不妨将这样的树称之为这个图的最短路径生成树

首先生成树中的边肯定是最短路径子图中的边

我来解释一下这个概念……

首先图是由点集和边集两个元素组成的

那么子图的点集和边集肯定是原图中的子集

最短路径子图的点集肯定和原图一样

顾名思义边集就是所有可能出现在最短路径中的边的集合

即E‘={e|dis[e.u]+e.l=dis[e.v]}

我们可以用显然法证明,最短路径生成树一定是最短路径子图的生成树

然鹅最短路径子图的生成树却并不一定是最短路径生成树_(:зゝ∠)_

举个例子

V={1,2,3},E={(1,2,1),(2,3,1),(1,3,2)}(最后一个元素代表边的长度)

显然这个图的每一条边都可能出现在最短路径中

所以这个图的最短路径子图就是它本身

{(1,3,2)(2,3,1)}是这个图的最短路径子图的一个生成树

然鹅并不是这个图的最短路径生成树,因为1到2的距离是3

有了以上的思路之后,我们可以先求出来最短路径子图

最短路径子图怎么求?

根据定义,跑一遍任何一个单源最短路算法(dij,SPFA),然后dis[i]+l[i][j]=dis[j]的边就是最短路径子图的边

然后我们将这些点按dis排序

假设我们现在已经求出了连通1...i-1这几个点的最短路径生成树个数

首先第i个点肯定是由1...i-1中的其中一个点连接的,而不可能是dis比i还大的那些点连接过来的。

然后1...i-1的生成树的形态和1...i-1中哪个点连接i这个点是没有关系的

也就是说这两个方案是相互独立的,计数中的互相独立意味着乘法原理的可行性

那么连通1...i的最短路径生成树个数就是1...i-1的生成树个数乘以1...i-1中任何一个点连接i这个点的最短路边的个数

讲完了

是不是很玄学……我也觉得,很想细讲但是发现没办法再讲了,自己脑补吧……

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<ctime>
 7 #include<algorithm>
 8 #include<queue>
 9 using namespace std;
10 #define INF 1000000000
11 #define MAXN 1010
12 #define mod ((1<<31)-1)
13 struct node1{long long y,next,v;}e[MAXN*MAXN];
14 struct node2{long long id,v;}dis[MAXN];
15 long long n,m,len,ans=1,Link[MAXN],vis[MAXN],q[MAXN],map[MAXN][MAXN];
16 inline long long read()
17 {
18     long long x=0,f=1;  char ch=getchar();
19     while(!isdigit(ch))  {if(ch==‘-‘)  f=-1;  ch=getchar();}
20     while(isdigit(ch))  {x=x*10+ch-‘0‘;  ch=getchar();}
21     return x*f;
22 }
23 void insert(long long x,long long y,long long v) {e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;}
24 bool cmp(node2 a,node2 b)  {return a.v<b.v;}
25 void spfa()
26 {
27     for(long long i=1;i<=n;i++)  dis[i].id=i,dis[i].v=INF;
28     long long head=0,tail=1;
29     q[1]=1;  vis[1]=1;  dis[1].v=0;
30     while(++head<=tail)
31     {
32         long long x=q[head];
33         for(long long i=Link[x];i;i=e[i].next)
34         {
35             if(dis[x].v+e[i].v<dis[e[i].y].v)
36             {
37                 dis[e[i].y].v=dis[x].v+e[i].v;
38                 if(!vis[e[i].y])
39                 {
40                     q[++tail]=e[i].y;
41                     vis[e[i].y]=1;
42                 }
43             }
44         }
45         vis[x]=0;
46     }
47 }
48 int main()
49 {
50     freopen("castle.in","r",stdin);
51     freopen("castle.out","w",stdout);
52     n=read();  m=read();
53     memset(map,10,sizeof(map));
54     for(long long i=1;i<=m;i++)
55     {
56         long long x=read(),y=read(),v=read();
57         insert(x,y,v);  insert(y,x,v);
58         map[x][y]=min(map[x][y],v);
59         map[y][x]=map[x][y];
60     }
61     spfa();
62     sort(dis+1,dis+n+1,cmp);
63     for(long long i=2;i<=n;i++)
64     {
65         long long temp=0;
66         for(long long j=1;j<i;j++)
67         {
68             long long x=dis[i].id,y=dis[j].id;
69             if(dis[i].v==dis[j].v+map[x][y])  temp++;
70         }
71         ans=ans*temp%mod;
72     }
73     printf("%d\n",ans);
74     return 0;
75 }

时间: 2024-10-06 20:44:41

1002 图论专练 解题报告的相关文章

1003 动规专练 解题报告

T1  卡车更新问题 (文件名:truck.pas/c/cpp) [题目描述] 某人购置了一辆新卡车, 从事个体运输业务. 给定以下各有关数据: R[t], t=0,1,2,...,k, 表示已使用过 t 年的卡车, 再工作一年所得的运费, 它随 t 的增加而减少, k (k≤20) 年后卡车已无使用价值. U[t]: t=0,1,...,k, 表示已使用过 t 年的卡车, 再工作一年所需的维修费, 它随 t 的增加而增加. C[t], t=0,1,2,...,k, 表示已使用过 t 年的旧卡车

BestCoder17 1002.Select(hdu 5101) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5101 题目意思:给出 n 个 classes 和 Dudu 的 IQ(为k),每个classes 都有相应的人,每个人又有相应的IQ.现在要求从这些classes挑选两个人,满足IQ之和 > k,不过要满足这两个人不能来自同一个class的. 解题思路不难想出,直接所有人两两之和 > k - 同一个class 两两之和 > k  就是答案了. 不过很容易超时!!!! 用二分就可以过了.二分有

BestCoder15 1002.Instruction(hdu 5083) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5083 题目意思:如果给出 instruction 就需要输出对应的 16-bit binary code,给出16-bit binary code 就需要输出对应的instruction. 由于不会截取的技巧,代码量非常可观 = =,所以说,一直很讨厌做模拟题!!! 留下这代码,纪念一个代码还是不够精简的自己!!!内存和时间还能接受,也比较容易理解,不过好多重复代码= =.以下这个可以代码可以忽略,

BestCoder20 1002.lines (hdu 5124) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5124 题目意思:给出 n 条线段,每条线段用两个整数描述,对于第 i 条线段:xi,yi 表示该条线段的左端点和右端点.设 A 表示最多线段覆盖的点(当然这个 A 可以有多个啦,但这个无关紧要).现在需要求的是 A 被多少条线段覆盖. 我是不会做啦.......一开始还看不懂题目= = 以下是按照题解做的, 题解中的最大区间和,实际上就是求最大连续子序列的和. 1 #include <iostrea

BZOJ 1051 最受欢迎的牛 解题报告

题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[Submit][Status][Discuss] Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎.你的任务是求出有多少头 牛被所有的牛

poj分类解题报告索引

图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Journey poj1724 - ROADS(邻接表+DFS) BFS poj3278 - Catch That Cow(空间BFS) poj2251 - Dungeon Master(空间BFS) poj3414 - Pots poj1915 - Knight Moves poj3126 - Prim

四月月赛解题报告

题目挂在wustoj上,不知道什么原因不能粘贴链接.. 第一题题号为1314..这题是智力题...换成7的阶乘就可以了.. 代码如下. #include<cstdio> int main() { printf("...............................................................................................\n"); printf("..#................

poj 1094 Sorting It All Out 解题报告

题目链接:http://poj.org/problem?id=1094 题目意思:给出 n 个待排序的字母 和 m 种关系,问需要读到第 几 行可以确定这些字母的排列顺序或者有矛盾的地方,又或者虽然具体的字母顺序不能确定但至少不矛盾.这些关系均是这样的一种形式: 字母1 < 字母2 这道题目属于图论上的拓扑排序,由于要知道读入第几行可以确定具体的顺序,所以每次读入都需要进行拓扑排序来检验,这时每个点的入度就需要存储起来,所以就有了代码中memcpy 的使用了. 拓扑排序的思路很容易理解,但写起来

解题报告 之 HDU5326 Work

解题报告 之 HDU5326 Work Description It's an interesting experience to move from ICPC to work, end my college life and start a brand new journey in company. As is known to all, every stuff in a company has a title, everyone except the boss has a direct le