HDU 6026 Deleting Edges
题目:http://acm.hdu.edu.cn/showproblem.php?pid=6026
题意:给出一个图,要求删除一些边,然后使得删除后的图是一颗树,并且各个点到0点的距离为原来图中的最短距离。
解法:Dijstra算出每个点到原点的距离,然后枚举每个点,计算它的临点到他的距离为它本身的最短距离数目,相乘即可
AC:
#include <iostream> #include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; typedef long long ll; const int MOD=1e9+7; ll n, dist[110], vis[110], a[110][110]; char b[110][110]; void dijkstra() { for(int i = 0; i < n; i++){ dist[i] = INF; } dist[0]=0; for(int i = 0; i < n; i++){ ll mini = INF, k=-1; for(int j = 0; j < n; j++){ if(!vis[j]&&dist[j]<mini){ mini = dist[j]; k = j; } } vis[k] = 1; for(int j = 0; j < n; j++){ if(!vis[j]&&a[k][j]&&dist[j] > dist[k]+a[k][j]){ dist[j] = dist[k]+a[k][j]; } } } } int main() { while(cin >> n) { memset(vis,0,sizeof(vis)); for(int i = 0; i < n; i++){ cin >> b[i]; for(int j = 0; j < n; j++){ a[i][j] = b[i][j]-'0'; } } dijkstra(); ll tmp, ans=1; for(int i = 1; i < n; i++){ tmp = 0; for(int j = 0; j < n; j++){ if(a[j][i]&&dist[i] == dist[j]+a[j][i]){ tmp++; } } ans = (ans*tmp)%MOD; } cout << ans << endl; } return 0; }