黑暗城堡(最短路徑樹)


黑暗城堡 

(castle.pas/c/cpp)

 

題目描述 

在順利攻破 Lord lsp 的防線之后,lqr 一行人來到了 Lord lsp 的城堡下方。Lord lsp 黑化之后雖然擁有了強大的超能力,能夠用意念力制造建築物,但是智商水平卻沒怎么增加。現 lqr 已經搞清楚黑暗城堡有個房間,條可以制造的雙向通道,以及每條通道的長度。 

lqr 深知 Lord lsp 的想法, 為了避免每次都要琢磨兩個房間之間的最短路徑,Lord lsp一定會把城堡修建成樹形的; 但是,為了盡量提高自己的移動效率,Lord lsp 一定會使得城堡滿足下面的條件:設 Di 為如果所有的通道都被修建, 號房間與第號房間的最短路徑長度;而 Si 為實際修建的樹形城堡中第號房間與第

號房間的路徑長度,對於所有滿足 1≤i≤N 的整數 i,有 Si = Di。為了打敗 Lord lsplqr 想知道有多少種不同的城堡修建方案。於是 lqr  applepi 提出了這個問題。由於 applepi 要忙着出模擬賽,所以這個任務就交給你了。當然,你只需要輸出答案對 231 – 1 取模之后的結果就行了。 

輸入格式 

第一行有兩個整數 N M 

之后行,每行三個整數 X L,表示可以修建之間的一條長度為的通道。 

輸出格式 

輸出一個整數,表示答案對 231 – 1 取模之后的結果。 

樣例輸入 

 

3

3

 

1

2

2

1

3

1

2

3

1

 

樣例輸出 

2

 

數據范圍與約定 

對於 30% 的數據,2≤N≤5M≤10 

對於 50%  的數據,滿足條件的方案數不超過 10000 

對於 100%  的數據,2≤N≤1000N – 1≤M≤N(N – 1)/21≤L≤100 

題目要求源點到其余點的最短路徑d[i],並且求樹上路徑s[i]等於d[i]的生成樹

所以先求出最短路徑d[i],並記錄d[i[是哪個點的最短路徑屬性為v;

然后按長度大小進行排序,為了避免重復計數,,最后把滿足d[x]=d[y]+w[i][j]的一個點一個點的往生成樹之中加

根據乘法原理求出答案即可

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
 
typedef long long ll;
 
const int maxn=1010;
const ll nil=(long long)1<<40-1;
#define mod ((1<<31)-1)
 
struct my{
       int v,next;
       ll w;
};
 
struct lmjer{
       int v;
       ll w;
};
 
struct node{
       int u;
       ll w;
       bool operator<(const node &rhs)const{
            return w>rhs.w;
       }
};
 
int fa,adj[maxn],n,m;
ll tu[maxn][maxn];
lmjer d[maxn];
bool done[maxn];
priority_queue<node>Q;
my bian[maxn*maxn];
 
void myinsert(int u,int v,ll w){
     bian[++fa].v=v;
     bian[fa].next=adj[u];
     bian[fa].w=w;
     adj[u]=fa;
}
 
void dijkstra(int s){
     for (int i=1;i<=n;i++) d[i].w=nil,d[i].v=i;
     d[s].w=0;
     node x;
     x.u=s;
     x.w=0;
     Q.push(x);
     while(!Q.empty()){
        x=Q.top();Q.pop();
        int u=x.u;
        if(done[u]) continue;
        done[u]=true;
        for (int i=adj[u];i;i=bian[i].next){
            int v=bian[i].v;
            if(d[v].w>d[u].w+bian[i].w){
                d[v].w=d[u].w+bian[i].w;
                x.u=v;
                x.w=d[v].w;
                Q.push(x);
            }
        }
     }
}
 
bool cmp(const lmjer a,const lmjer b){
     return a.w<b.w;
}
 
int main(){
    scanf("%d%d",&n,&m);
    memset(tu,10,sizeof(tu));
    int u,v;
    ll w;
    for (int i=1;i<=m;i++){
        scanf("%d%d%lld",&u,&v,&w);
        myinsert(u,v,w);
        myinsert(v,u,w);
        tu[u][v]=tu[v][u]=min(tu[u][v],w);
    }
    dijkstra(1);
    sort(d+1,d+1+n,cmp);
    int ans=1;
    for (int i=2;i<=n;i++){
            ll temp=0;
        for (int j=1;j<i;j++){
            int x=d[i].v,y=d[j].v;
            if(d[i].w==d[j].w+tu[x][y]) temp++;
        }
    ans=(long long)ans*temp%mod;
    }
    printf("%d\n",ans);
return 0;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM