HDU 6026 Deleting Edges【图论】

来源:互联网 发布:php比较好的书籍 编辑:程序博客网 时间:2024/06/07 05:07

题目链接

题意:n个顶点编号为0到n-1的图,从中删去一些边形成一棵树,保证树上任意一个点到0点的距离等于原图中0到这个点的最短路长度。求这棵树有多少种画法。

先用dijkstra算法求出原图中0点到每个点的最短路的长度,再暴力的跑一遍判断两个点A和B形成的边是否能等于A到中间点C加上C到B的长度,如果可以,就可以用这个边代替原来的边,最后相乘就是答案。要模除mod。

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define ll long longconst int INF = 0x3f3f3f3f;const int mod = 1000000000 + 7;int n;int e[55][55];bool vis[55];int d[55];void dij(int n){memset(vis, false, sizeof(vis));memset(d, INF, sizeof(d));d[0] = 0;vis[0] = true;for (int i = 1; i <= n - 1; i++){int u = 0, MIN = INF;for (int j = 0; j < n; j++){if (!vis[j] && d[j] < MIN){MIN = d[j];u = j;}}vis[u] = true;for (int v = 0; v < n; v++){if (!vis[v]){if (d[v] > d[u] + e[u][v])d[v] = d[u] + e[u][v];}}}}int main(){while (scanf("%d", &n) != EOF){for (int i = 0; i < n; i++)for (int j = 0; j < n; j++){char ch;scanf(" %c", &ch);e[i][j] = ch - '0';if (e[i][j] == 0 && i != j)e[i][j] = INF;}dij(n);ll ans = 1;for (int i = 1; i < n; i++){ll cnt = 0;for (int j = 0; j < n; j++){if (e[i][j] && d[i] == d[j] + e[j][i])cnt++;}ans = ans * cnt % mod;}printf("%lld\n", ans);}return 0;}


原创粉丝点击