zoukankan      html  css  js  c++  java
  • UVA 125 Numbering Paths

    题目大意:给定n条单向边,求图中任意两点的连通路径的数目。其中点是从0-输入中出现的最大的点。

    可以用floyd-warshall算法或者dfs.

    for(int k = 0; k < n; k++)

    for(int i = 0; i < n; i ++)

    for(int j = 0; j < n; j++)

    dp[i][j] += dp[i][k] * dp[k][j];

    这里这样写是不会重复的,原因在于k循环时,可能产生重复情况的 点对应的d[k][j]或d[i][k]为0,因此一条分支路径上最终只会算一遍,不同的分叉加起来就是总数目。

    在判断环存在时,若dp[k][k]不为0,说明k点在环上,所有路径经过k的dp[i][j]都应该变成-1,也就是对应无数条这样的i->j的通路。

    1 #include <cstdio>
    2 #include <cstring>
    3 #include <cstdlib>
    4 #include <algorithm>
    5 #define N 30
    6 using namespace std;
    7 int n, m, dp[N][N];
    8
    9 void floyd(void)
    10 {
    11 for(int k = 0; k < n; k++)
    12 for(int i = 0; i < n; i++)
    13 for(int j = 0; j < n; j++)
    14 dp[i][j] += dp[i][k] * dp[k][j];
    15 for(int k = 0; k < n; k++)
    16 if(dp[k][k])
    17 for(int i = 0; i < n; i++)
    18 for(int j = 0; j < n; j++)
    19 if(dp[i][k] && dp[k][j])
    20 dp[i][j] = -1;
    21
    22 }
    23
    24 void out(void)
    25 {
    26 for(int i = 0; i < n; i++)
    27 {
    28 for(int j = 0; j < n; j++)
    29 printf("%d%c",dp[i][j], (j == n-1)? ' ':' ');
    30
    31 }
    32 }
    33 int main(void)
    34 {
    35 int t = 0;
    36 while(~scanf("%d", &m))
    37 {
    38 n = 0;
    39 memset(dp, 0, sizeof(dp));
    40 printf("matrix for city %d ", t++);
    41 while(m--)
    42 {
    43 int a, b;
    44 scanf("%d%d",&a, &b);
    45 dp[a][b] = 1;
    46 n = max(n, max(a, b));
    47 }
    48 n++;
    49 floyd();
    50 out();
    51 }
    52 return 0;
    53 }
    或者采用dfs的方法,代码参考于这位大神:

    http://www.cnblogs.com/devymex/archive/2010/08/17/1801126.html

    其实我自己又照着写了一遍,稍微改动了。

    我来再叙述一遍加深自己的理解:

    通过vector<int>Path保存经过的点,并在dfs搜索下一个点之后再已经走过的Path里面查找看是否存在相应点,如果存在说明该重复结点到Path的最后一个点形成环,应该把数目设成-1,然后跳过改重复点,dfs下一个结点,注意每次dfs完之后都要将相应结点从Path里面移出来,

    1 #include <cstdio>
    2 #include <cstring>
    3 #include <algorithm>
    4 #include <vector>
    5 using namespace std;
    6 #define N 30
    7 #define Rep(i,c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
    8 vector<int> g[N];
    9 int res[N][N];
    10
    11 void dfs(vector<int> &Path)
    12 {
    13 vector<int> &temp = g[Path.back()];
    14 Rep(i,temp)
    15 {
    16 vector<int> ::iterator j = Path.begin();
    17 for(; j != Path.end(); j++)
    18 if(*j == *i)
    19 break;
    20 if(j != Path.end())
    21 {
    22 for(; j != Path.end(); j++)
    23 res[*j][*j] = -1;
    24 continue;
    25 }
    26 res[Path.front()][*i] ++;
    27 Path.push_back(*i);
    28 dfs(Path);
    29 Path.pop_back();
    30 }
    31 }
    32
    33 int main(void)
    34 {
    35 int t = 0;
    36 int m, n;
    37 while(~scanf("%d", &m))
    38 {
    39 memset(res, 0,sizeof(res));
    40 n = 0;
    41 printf("matrix for city %d ", t++);
    42 for(int i = 0; i < N; i++)
    43 g[i].clear();
    44 while(m--)
    45 {
    46 int a, b;
    47 scanf("%d%d",&a, &b);
    48 g[a].push_back(b);
    49 n = max(n, max(a, b));
    50 }
    51 n++;
    52 for(int i = 0; i < n; i++)
    53 {
    54 vector<int> Path(1,i);
    55 dfs(Path);
    56 }
    57 for(int k = 0; k < n; k++)
    58 if(res[k][k] == -1)
    59 for(int i = 0; i < n; i++)
    60 for(int j = 0; j < n; j++)
    61 if(res[i][k] && res[k][j])
    62 res[i][j] = -1;
    63 for(int i = 0; i < n; i++)
    64 for(int j = 0; j < n; j++)
    65 printf("%d%c", res[i][j],(j == n-1)?' ':' ');
    66 }
    67 return 0;
    68 }

  • 相关阅读:
    51 Nod 1035 最长的循环节 (此题还不是很懂,日后再看)
    51 Nod 1101 换零钱(动态规划好题)
    51 Nod 1101 换零钱(动态规划好题)
    51 Nod 1163 最高的奖励
    51 Nod1042 数字0到9的数量
    51 Nod 1629 B君的圆锥
    iterrows(), iteritems(), itertuples()对dataframe进行遍历
    pandas计数 value_counts()
    scikit_learn逻辑回归类库
    Python中的深拷贝和浅拷贝
  • 原文地址:https://www.cnblogs.com/rootial/p/3303625.html
Copyright © 2011-2022 走看看