zoukankan      html  css  js  c++  java
  • 表示:

    邻接链表:稀疏图

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

    bfs:

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

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

    灰色不一定。颜色属性

    最短路径

    广度优先树

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

    深度优先树不相交,树边

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

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

    解决括号化结构

    递归靠压栈来完成

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

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

    uva,10336

    注意:

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

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

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

    3 对截止字符处理不同。
    gets函数会读入截止字符 , 同时将 自动替换为.
    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把接收回车并把'
    '转换为''
    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
    ",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
    ",'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
    ",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("
    ");
    59             return;
    60         }
    61     }
    62     printf("no arbitrage sequence exists
    ");
    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
    ",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
    ",k++);
    46         else printf("%d B
    ",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]=='')
    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
    ",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
    ");
    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
    ");
    62             else
    63                 printf("Not Possible
    ");
    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
    ",index);
    64     }
    65     return 0;
    66 }
    View Code
    活在现实,做在梦里。
  • 相关阅读:
    SpringCloud之架构搭建
    3.通用权限设计——SnailAspNetCoreFramework快速开发框架之后端设计
    2.接口输入校验、输出格式、及异常处理——SnailAspNetCoreFramework快速开发框架之后端设计
    1、框架内各项目及目录的介绍和总设计思路——SnailAspNetCoreFramework快速开发框架
    SnailAspNetCoreFramework框架系列博客
    Asp.net core中间件实现原理及用法解说
    深入剖析linq的联接
    webapi框架搭建系列博客
    webapi框架搭建-依赖注入之autofac
    webapi框架搭建-创建项目(三)-webapi owin
  • 原文地址:https://www.cnblogs.com/do-it-best/p/5382500.html
Copyright © 2011-2022 走看看