表示:

邻接链表:稀疏图

邻接矩阵:稠密图,快判两个节点之间是否有边

bfs:

广度优先搜索树:既可用于有向和无向

所有与黑色节点相连接的节点都是以发现。

灰色不一定。颜色属性

最短路径

广度优先树

 

深度优先树:树边,前驱子图,深度优先树,深度优先森林

深度优先树不相交,树边

两个时间戳,一个纪录被发现,一个纪录完成了

u.d u.f在1到2|V|之间

解决括号化结构

递归靠压栈来完成

有向图有前向后向边横向边数边

无向图:无前向边和横向边

 

uva,10336

注意:

都是从输入流中读取数据,但功能有很大差别:
1 操作类型不同。
gets函数仅用于读入字符串。
scanf为格式化输出函数,可以读入任意C语言基础类型的变量值,而不是仅限于字符串(char*)类型。

2 截止字符不同。
gets函数固定的以换行符作为结尾,遇到换行符时结束输入。

scanf函数默认以空白函数结尾,同时可以对截止函数进行修改。

3 对截止字符处理不同。
gets函数会读入截止字符\n, 同时将\n自动替换为\0.
scanf遇到截止字符时不会继续读取,截止字符将存储于输入缓冲中。

4 返回值类型不同。
gets的返回值为char*型,当读入成功时会返回输入的字符串指针地址,出错时返回NULL。
scanf返回值为int型,返回实际成功赋值的变量个数,当遇到文件结尾标识时返回EOF。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 
 6 using namespace std;
 7 
 8 char map[100][100];
 9 int sets[128];
10 
11 int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
12 
13 void dfs(int x,int y,int m,int n,char c)
14 {
15     if(x<0 || x>=m || y<0 || y>=n || map[x][y]!=c)
16         return;
17     map[x][y]=0;      
18     for(int k=0;k<4;k++)
19     {
20         dfs(x+dx[k],y+dy[k],m,n,c);
21     }
22 }
23 
24 int main()
25 {
26     int t;
27     int m,n;
28     while(~scanf("%d",&t) && t)
29     for(int k=1;k<=t;k++)
30     {
31         scanf("%d %d",&m,&n);
32         
33         int i,j;
34         for(i=0;i<m;i++)
35             scanf("%s",map[i]);   //不能用gets()
36 //因为gets把接收回车并把'\n'转换为'\0'
37 //scanf不接收回车,放入下一行。而scanf函数可以识别空格结束。
38 //会比scanf多一列。。。
39         
40         memset(sets,0,sizeof(sets));
41         int maxs=0;
42         for(i=0;i<m;i++)
43             for(j=0;j<n;j++)
44             {
45                 if(!sets[map[i][j]] && map[i][j])
46                 {
47                     sets[map[i][j]]=1;
48                     int count=0;
49                     char temp=map[i][j];
50                     
51                     for(int p=0;p<m;++p)
52                         for(int q=0;q<n;++q)
53                         {
54                             if(map[p][q]==temp)
55                             {
56                                 dfs(p,q,m,n,temp);
57                                 count++;
58                             }
59                         }
60                     sets[temp]=count;
61                     if(maxs<count)
62                         maxs=count;
63                     
64                 }
65             }
66         printf("World #%d\n",k);
67         for(int i=maxs;i;--i)
68             for(int j=0;j<26;++j)
69             {
70                 if(sets['a'+j]==i)
71                     printf("%c: %d\n",'a'+j,i);
72             }
73     }
74     return 0;
75 }
View Code

uva,315

对于新手的我,刚刚把dfs和bfs看了一遍就过来做题目。大概知道具体的意识。但是解法就一脸懵逼。

于是去网上搜了一下。知道了是解强联通图/强联通分量的割点的问题。具体用tarjan模版套一套就好咯。。。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <vector>
 6 #include <sstream>
 7 
 8 using namespace std;
 9 
10 int dfs_time;
11 int dfn[105],low[105];
12 int ans;
13 vector<int> edge[105];
14 
15 void dfs(int cur,int parent)
16 {
17     bool flag=false;
18     int child=0;
19     dfn[cur]=low[cur]=++dfs_time;
20     
21     
22     for(int i=0;i<edge[cur].size();++i)
23     {
24         int nxt=edge[cur][i];
25         if(!dfn[nxt])
26         {
27             ++child;
28             dfs(nxt,cur);
29             low[cur]=min(low[cur],low[nxt]);
30             
31             if(low[nxt]>=dfn[cur])
32                 flag=true;
33         }
34         else if(nxt!=parent)
35             low[cur]=min(low[cur],dfn[nxt]);
36     }
37     
38     if((child>=2 || parent!=-1) && flag)
39         ++ans;
40 }
41 
42 int main()
43 {
44     int n;
45     string line;
46     while(scanf("%d ",&n),n) //注意%d后面有一空格,输出啊。。。
47     {
48         ans=0;
49         dfs_time=0;   //纪录时间戳
50         for(int i=0;i<=n;i++)
51         {
52             dfn[i]=0;
53             low[i]=0;
54             edge[i].clear();
55         }
56         
57         int a,b;
58         while(getline(cin,line))
59         {
60             stringstream ss(line);   //不确定输出用流解决。但是耗时
61             ss >> a; 
62             if(!a) break;
63             while(ss >> b)
64             {
65                 edge[a].push_back(b);
66                 edge[b].push_back(a);
67             }
68             
69         }
70         
71         dfs(1,-1);
72         
73         printf("%d\n",ans);
74     }
75 }
View Code

 uva,104

Floyd算法

g[i][j][p]表示进过p次交换的最大利率。其实就是模拟建图然后用求最短路的思想求出最大利率。

最后比较当存在一个值大1.01就找到。其输出也是folyd的一部分

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 
 5 using namespace std;
 6 const int maxn=25;
 7 
 8 int n;
 9 double g[maxn][maxn][maxn];
10 int d[maxn][maxn][maxn];
11 
12 void init()
13 {
14     memset(g,0,sizeof(g));
15     int i,j;
16     
17     for(i=0;i<n;i++)
18         for(j=0;j<n;j++)
19         {
20             if(i!=j)
21             {
22                 scanf("%lf",&g[i][j][1]);
23                 d[i][j][1]=i;
24             }
25         }
26 }
27 
28 void print(int x,int y,int p)
29 {
30     if(p==0)
31         printf("%d",x+1);
32     else
33     {
34         print(x,d[x][y][p],p-1);
35         printf(" %d",y+1);
36     }
37 }
38 
39 void Floyd()
40 {
41     int i,j,k,p;
42     for(p=1;p<n;p++)
43     {
44         for(k=0;k<n;k++)
45             for(i=0;i<n;i++)
46                 for(j=0;j<n;j++)
47                 {
48                     if(g[i][k][p]*g[k][j][1]>g[i][j][p+1]+1e-9)
49                     {
50                         g[i][j][p+1]=g[i][k][p]*g[k][j][1];
51                         d[i][j][p+1]=k;
52                     }
53                 }
54     for(i=0;i<n;i++)
55         if(g[i][i][p+1]>1.01)
56         {
57             print(i,i,p+1);
58             printf("\n");
59             return;
60         }
61     }
62     printf("no arbitrage sequence exists\n");
63 }
64 
65 int main()
66 {
67     while(~scanf("%d",&n))
68     {
69         init();
70         Floyd();
71     }
72     return 0;
73 }
View Code

 HDU,4401

dfs找到一个四周存在'#'的中心点并标记。然后bfs判断这个中心点是不是对的。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cstring>
  5 
  6 using namespace std;
  7 const int maxn=55;
  8 int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
  9 char ch[maxn][maxn];
 10 int vis[maxn][maxn];
 11 int center[maxn][maxn];
 12 int n;
 13 int cnt;
 14 
 15 struct Node
 16 {
 17     int x,y;
 18 }q[11111];
 19 
 20 bool check(int x,int y)
 21 {
 22     if(x<0 || x>=n || y<0 || y>=n) return false;
 23     if(vis[x][y]) return false;
 24     if(ch[x][y]!='#') return false;
 25     return true;
 26 }
 27 
 28 
 29 void dfs(int x,int y)
 30 {
 31     int num=0;
 32     int xx,yy;
 33     for(int i=0;i<4;i++)
 34     {
 35         xx=x+dx[i];
 36         yy=y+dy[i];
 37         if(check(xx,yy))
 38         {
 39             num++;
 40             vis[x][y]=1;
 41             dfs(xx,yy);
 42         }
 43     }
 44     if(num==3)
 45         center[x][y]=1;
 46 }
 47 
 48 void bfs(int x,int y)
 49 {
 50     int head=0,tail=0;
 51     q[head].x=x;
 52     q[head++].y=y;
 53     int cut=4;
 54     vis[x][y]=1;
 55     while(head!=tail)
 56     {
 57         int num=0;
 58         Node t=q[tail++];
 59         Node tt;
 60         for(int i=0;i<4;i++)
 61         {
 62             tt.x=t.x+dx[i];
 63             tt.y=t.y+dy[i];
 64             if(check(tt.x,tt.y))
 65             {
 66                 num++;
 67                 vis[tt.x][tt.y]=1;
 68                 q[head++]=tt;
 69             }
 70         }
 71         if(num==1) cut++;
 72     }
 73     cut=cut/4;
 74     if(cut*4+1==head) cnt++;
 75 }
 76 
 77 
 78 int main()
 79 {
 80     while(scanf("%d",&n),n)
 81     {
 82         memset(center,0,sizeof(center));
 83         cnt=0;
 84         for(int i=0;i<n;i++)
 85             scanf("%s",ch[i]);
 86         
 87         memset(vis,0,sizeof(vis));
 88         for(int i=0;i<n;i++)
 89             for(int j=0;j<n;j++)
 90             {
 91                 if(!vis[i][j] && ch[i][j]=='#')
 92                 {
 93                     vis[i][j]=1;
 94                     dfs(i,j);
 95                 }
 96             }
 97         
 98         
 99         memset(vis,0,sizeof(vis));
100         for(int i=0;i<n;i++)
101             for(int j=0;j<n;j++)
102             {
103                 if(center[i][j] && !vis[i][j])
104                 {
105                     memset(q,0,sizeof(q));
106                     bfs(i,j);
107                 }
108             }
109         printf("%d\n",cnt);
110     }
111     return 0;
112 }
View Code

uva,260

黑的从上往下走横行,白的从左往右走纵行,每次走能走上下左右以及左上右下。

给你一盘下满的棋,问你那个赢。一开始写了个判断深度的,发现

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 
 5 using namespace std;
 6 const int maxn=205;
 7 int dx[]={-1,-1,0,0,1,1},dy[]={-1,0,-1,1,0,1};
 8 int n;
 9 int cnt;
10 char map[maxn][maxn];
11 
12 
13 int dfs(int x,int y,int n)
14 {
15     if(x==n) return 1;
16     if(x<0 || x>=n || y<0 || y>=n) return 0;
17     if(map[x][y]!='b') return 0;
18     map[x][y]='#';
19     int max=0;
20     for(int i=0;i<6;i++)
21     {
22         max |=dfs(x+dx[i],y+dy[i],n);    //不知道什么鬼
23     }
24     return max;
25 }
26 
27 int main()
28 {
29     int k=1;
30     while(scanf("%d",&n),n)
31     {
32         int i;
33         int flag=0;
34         for(i=0;i<n;i++)
35             scanf("%s",map[i]);
36         for(i=0;i<n;i++)
37         {
38             if(map[0][i]=='b' && dfs(0,i,n))
39             {
40                 flag=1;
41                 break;
42             }
43         }
44         if(!flag)
45             printf("%d W\n",k++);
46         else printf("%d B\n",k++);
47     }
48     return 0;
49 }
View Code

 uva,469

不确定输入的强大。。。sscanf(str,"%d %d",&i,&j)再一次震撼~

给你一个网格盘有水和土地,再给你其中一个水格的坐标让你找出它附近共有多少个水格子,dfs八个方向深搜。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 
 6 using namespace std;
 7 const int maxn=105;
 8 int dx[]={-1,0,-1,-1,0,1,1,1},dy[]={-1,-1,0,1,1,-1,0,1};
 9 
10 char map[maxn][maxn];
11 int vis[maxn][maxn];
12 int cnt;
13 
14 void dfs(int x,int y)
15 {
16     if(x<0 || y<0 || !map[x][y]) return;
17     if(map[x][y]!='W') return;
18     if(vis[x][y]) return;
19     
20     vis[x][y]=1;cnt++;
21     for(int i=0;i<8;i++)
22         dfs(x+dx[i],y+dy[i]);
23 }
24 
25 int main()
26 {
27     int t;
28     int i,j;
29     char str[105];
30     scanf("%d ",&t);
31     while(t--)
32     {
33         int n=0;
34         memset(map,0,sizeof(map));
35         while(gets(str))
36         {
37             if(str[0]=='\0')
38                 break;
39             
40             if(str[0]!='W' && str[0]!='L')
41             {
42                 sscanf(str,"%d %d",&i,&j);
43                 memset(vis,0,sizeof(vis));
44                 cnt=0;
45                 dfs(i-1,j-1);
46                 printf("%d\n",cnt);
47             }
48             else
49                 sscanf(str,"%s",map[n++]);
50         }
51         if(t)
52             puts("");
53     }
54     return 0;
55 }
View Code

uva,10596

欧拉回路

加边减边,vis加加减减

前面写过一个判点是否全部在的,老是各种错误。。lld什么的

而且我试了一下,欧拉回路的判断条件:全是偶数度的点,或者终点和起点是奇数度其他全为偶数度(感觉第二个不用)

再就是dfs去扫。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 const int maxn=205;
 7 
 8 int G[maxn][maxn],vis[maxn];
 9 
10 int n,r;
11 
12 void dfs(int x)
13 {
14     for(int i=0;i<n;i++)
15     {
16         if(G[x][i])
17         {
18             G[x][i]--;
19             G[i][x]--;
20             vis[i]--;
21             vis[x]--;
22             dfs(i);
23         }
24     }
25 }
26 
27 int main()
28 {
29     while(~scanf("%d %d",&n,&r))
30     {
31         int s,e;
32         memset(G,0,sizeof(G));
33         memset(vis,0,sizeof(vis));
34         
35         for(int i=0;i<r;i++)
36         {
37             scanf("%d %d",&s,&e);
38             G[s][e]++;
39             G[e][s]++;
40             vis[e]++;
41             vis[s]++;
42         }
43         
44         int cnt=0;
45         for(int i=0;i<n;i++)
46             if(vis[i] & 1)
47             {
48                 cnt++;
49                 break;
50             }
51         
52         if(cnt || r<2) printf("Not Possible\n");
53         else
54         {
55             int flag=true;
56             dfs(0);
57             
58             for(int i=0;i<n;i++)
59                 if(vis[i])
60                     flag=false;
61             if(flag) printf("Possible\n");
62             else
63                 printf("Not Possible\n");
64         }
65     }
66     return 0;
67 }
View Code

 uva,10926

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 
 6 using namespace std;
 7 
 8 const int maxn=105;
 9 int map[maxn][maxn];  //一开始用的queue但是每次扫一次就清空了, 
10 //wa了几次
11 int cnt[maxn];
12 int vis[maxn];
13 int ans;
14 int n;
15 
16 void dfs(int t)
17 {
18     for(int i=1;i<=n;i++)
19     {
20         if(map[t][i] && !vis[i])
21         {
22             ans++;
23             vis[i]=1;
24             dfs(i);
25         }
26     }
27 }
28 
29 int main()
30 {
31     while(scanf("%d",&n),n)
32     {
33         
34         int t,b;
35         memset(map,0,sizeof(map));
36         for(int i=1;i<=n;i++)
37         {
38             scanf("%d",&t);
39             for(int j=0;j<t;j++)
40             {
41                 scanf("%d",&b);
42                 map[i][b]=1;
43             }
44         }
45         memset(cnt,0,sizeof(cnt));
46         for(int i=1;i<=n;i++)
47         {
48                 memset(vis,0,sizeof(vis));
49                 ans=0;
50                 dfs(i);
51                 cnt[i]+=ans;
52         }
53         int max=0;
54         int index=0;
55         for(int i=1;i<=n;i++)
56         {
57             if(max<cnt[i])
58             {
59                 max=cnt[i];
60                 index=i;
61             }
62         }
63         printf("%d\n",index);
64     }
65     return 0;
66 }
View Code

 

posted @ 2016-04-12 14:16  指尖泛出的繁华  阅读(154)  评论(0编辑  收藏  举报