题目大意:给定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)? '\n':' ');
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\n", 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\n", 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)?'\n':' ');
66 }
67 return 0;
68 }

UVA 125 Numbering Paths的更多相关文章

  1. UVA 10564 十 Paths through the Hourglass

     Paths through the Hourglass Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & % ...

  2. hdu1625 Numbering Paths (floyd判环)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission ...

  3. UVA 10000 Longest Paths (SPFA算法,模板题)

    题意:给出源点和边,边权为1,让你求从源点出发的最长路径,求出路径长度和最后地点,若有多组,输出具有最小编号的最后地点. #include <iostream> #include < ...

  4. uva 125

    floyd 算法   如果存在无数条路  则存在a->a的路  a->b的路径数等于 a->i 和 i->b(0=<i<=_max) 路径数的乘积和 #includ ...

  5. UVa 988 - Many Paths, One Destination

    称号:生命是非常多的选择.现在给你一些选择(0~n-1),和其他选项后,分支数每一次选择,选择共求. 分析:dp,图论.假设一个状态也许是选择的数量0一个是,代表死亡,计数的路径数将达到所有死亡可以去 ...

  6. UVa 10564 DP Paths through the Hourglass

    从下往上DP,d(i, j, k)表示第(i, j)个格子走到底和为k的路径条数. 至于字典序最小,DP的时候记录一下路径就好. #include <cstdio> #include &l ...

  7. UVA 125 统计路径条数 FLOYD

    这道题目折腾了我一个下午,本来我的初步打算是用SPFA(),进行搜索,枚举出发点,看看能到达某个点多少次,就是出发点到该点的路径数,如果出现环,则置为-1,关键在于这个判环过程,如果简单只找到某个点是 ...

  8. UVA题目分类

    题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics ...

  9. HOJ题目分类

    各种杂题,水题,模拟,包括简单数论. 1001 A+B 1002 A+B+C 1009 Fat Cat 1010 The Angle 1011 Unix ls 1012 Decoding Task 1 ...

随机推荐

  1. Android studio 删除Module、project

    很简单: 1 选中项目右键:Open Module Setting 2 选择要删除的项目,点击“-”即可

  2. SQL 分组后取最小行号记录

    本示例测试两个表联接查询后,分组并取分组后的最小行号记录 测试表: tb1表结构如下: CREATE TABLE [dbo].[tb1]( ) NOT NULL, ) NULL, ) NULL, CO ...

  3. WCF编程系列(三)地址与绑定

    WCF编程系列(三)地址与绑定   地址     地址指定了接收消息的位置,WCF中地址以统一资源标识符(URI)的形式指定.URI由通讯协议和位置路径两部分组成,如示例一中的: http://loc ...

  4. C# 数据类型映射 (SQLite,MySQL,MSSQL,Oracle)

    一.C# vs SQLite: C# SQLite 字段名 类型 库类型 GetFieldType(#) 转换 备注 F_BOOL bool BIT NOT NULL Boolean F_BOOL_N ...

  5. iOS 详细解释@property和@synthesize关键字

    /** 注意:由@property声明的属性 在类方法中通过下划线是获取不到的 必须是通过 对象名.属性 才能获取到!- @property和@synthesize关键字是针对成员变量以及get/se ...

  6. windows phone 操作 http异步返回结果

    wp中为了提升用户体验,砍掉了http的同步操作,仅支持http异步请求,那么该如何及时处理异步操作返回的结果.纠结了很久,终于在技术群中好友的帮助下解决了问题,借助事件,将异步编程模型模式简单的处理 ...

  7. 使用json方式实现省市两级下拉级联菜单[原创]

    本文为博主原创,转载请注明. 首先看一下实现后的效果图: 当然,要完成这个实验,mysql必须与数据库连接,这里选用navicat for mysql这款软件,它与mysql的契合度是很高的,配置环境 ...

  8. Sublime Text 3使用技巧总结--快捷键及常用插件

    1.Goto Anything(快速搜索) |--Ctrl+p 输入|--①文件名 |--②@+函数名 |--③:+数字 ->跳转到相应行 |--④#+变量名 2.多行游标 |--|--Alt+ ...

  9. POJ1182并查集

    食物链 时间限制:1000 ms  |  内存限制:65535 KB 难度:5   描述 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形.A吃B, B吃C,C吃A. 现有N个动物, ...

  10. Your branch and 'origin/master' have diverged

    git fetch origin git reset --hard origin/master