HDU 6026(最短路)

    题面:

Deleting Edges

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1154    Accepted Submission(s): 407


Problem Description
Little Q is crazy about graph theory, and now he creates a game about graphs and trees.
There is a bi-directional graph with n nodes, labeled from 0 to n1. Every edge has its length, which is a positive integer ranged from 1 to 9.
Now, Little Q wants to delete some edges (or delete nothing) in the graph to get a new graph, which satisfies the following requirements:
(1) The new graph is a tree with n1 edges.
(2) For every vertice v(0<v<n), the distance between 0 and v on the tree is equal to the length of shortest path from 0 to v in the original graph.
Little Q wonders the number of ways to delete edges to get such a satisfied graph. If there exists an edge between two nodes i and j, while in another graph there isn't such edge, then we regard the two graphs different.
Since the answer may be very large, please print the answer modulo 109+7.
 

Input
The input contains several test cases, no more than 10 test cases.
In each test case, the first line contains an integer n(1n50), denoting the number of nodes in the graph.
In the following n lines, every line contains a string with n characters. These strings describes the adjacency matrix of the graph. Suppose the j-th number of the i-th line is c(0c9), if c is a positive integer, there is an edge between i and j with length of c, if c=0, then there isn't any edge between i and j.
The input data ensure that the i-th number of the i-th line is always 0, and the j-th number of the i-th line is always equal to the i-th number of the j-th line.
 

Output
For each test case, print a single line containing a single integer, denoting the answer modulo 109+7.
 

Sample Input
2 01 10 4 0123 1012 2101 3210
 

Sample Output
1 6
 

Source
 

    题目描述:给你一张图,每次你都可以删除一条边,要求删除的边之后,整个图的最短路不发生改变。问一共会有多少种图的可能性。
    题目分析:这是一道最短路的变形思维题。拿到题目时,我们不能看到题目中要求我们删边而被删边限制住了思维。首先我们得思考,如果删除掉一条边,而使整张图的最短路不变,那么可以认为,这条路径是对整张图的最短路没有贡献的。再进一步思考,如果一条路径对最短路没有贡献,那么可以看作在跑最短路的过程的松弛操作中,d[to]==cost+d[pre]; 即此时的这条路径跟原有最短路径重合,因此这条边即使可以删去的边。因此我们在跑最短路的过程中,不断寻找满足路径等于原有最短路的边,并使这条路径的子结点的入度加一(表示存在这么一条可以删的边)。最后我们只需要枚举所有的点,将所有可以删除的边累乘起来即是我们所要求的答案。

    

#include <bits/stdc++.h>
#define maxn 55
#define maxm 5008
using namespace std;
typedef pair<int,int>PLL;
typedef long long ll;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
struct edge{
    int next,to,cost;
}q[maxm];
int head[maxm],cnt,d[maxm];
int n;
ll inde[maxm];
bool vis[maxm];
char str[maxn][maxn];
void add_edge(int from,int to,int cost){
    q[cnt].cost=cost;
    q[cnt].to=to;
    q[cnt].next=head[from];
    head[from]=cnt++;
}
void dijk(){
    priority_queue<PLL,vector<PLL>,greater<PLL> >que;
    memset(vis,0,sizeof(vis));
    memset(d,INF,sizeof(d));
    d[0]=0;
    que.push(PLL(0,0));
    inde[0]=1;
    while(!que.empty()){
        PLL p=que.top();
        que.pop();
        int x=p.second;
        vis[x]=1;
        for(int i=head[x];i!=-1;i=q[i].next){
            edge e=q[i];
            if(vis[e.to]) continue;
            if(d[e.to]>p.first+e.cost){
                inde[e.to]=1;
                d[e.to]=p.first+e.cost;
                que.push(PLL(d[e.to],e.to));
            }
            else if(d[e.to]==p.first+e.cost){
                inde[e.to]++;
            }
        }
    }
}
void init(){
    memset(head,-1,sizeof(head));
    cnt=0;
}
int main()
{
    while(cin>>n){
        init();
        for(int i=0;i<n;i++){
            scanf("%s",str[i]);
            for(int j=0;j<n;j++){
                if(str[i][j]!='0'){
                    add_edge(i,j,str[i][j]-'0');
                }
            }
        }
        dijk();
        ll ans=1;
        for(int i=0;i<n;i++){
            ans*=inde[i];
            ans%=mod;
        }
        cout<<ans<<endl;
    }
    return 0;
}

posted @ 2018-04-21 09:33  ChenJr  阅读(91)  评论(0编辑  收藏  举报