zoukankan      html  css  js  c++  java
  • [LOJ#10064]黑暗城堡

    Description
    在顺利攻破 Lord lsp 的防线之后,lqr 一行人来到了 Lord lsp 的城堡下方。Lord lsp 黑化之后虽然拥有了强大的超能力,能够用意念力制造建筑物,但是智商水平却没怎么增加。现在 lqr 已经搞清楚黑暗城堡有 N 个房间,M 条可以制造的双向通道,以及每条通道的长度。lqr 深知 Lord lsp 的想法,为了避免每次都要琢磨两个房间之间的最短路径, Lord lsp一定会把城堡修建成树形的;但是,为了尽量提高自己的移动效率,Lord lsp 一定会使得城堡满足下面的条件:设 Di为如果所有的通道都被修建,第 i 号房间与第 1 号房间的最短路径长度;而 Si 为实际修建的树形城堡中第 i 号房间与第1 号房间的路径长度,对于所有满足 1≤i≤N 的整数 i,有 Si = Di。为了打败 Lord lsp,lqr想知道有多少种不同的城堡修建方案。于是 lqr 向 applepi 提出了这个问题。由于 applepi 还要忙着出模拟赛,所以这个任务就交给你了。当然,你只需要输出答案对 2^31 – 1 取模之后的结果就行了.

    Input
    第一行有两个整数 N 和 M。
    之后 M 行,每行三个整数 X,Y 和 L,表示可以修建 X 和 Y 之间的一条长度为 L 的通道。
    2≤N≤1000,N – 1≤M≤N(N – 1)/2,1≤L≤100

    Output
    输出一个整数,表示答案对 2^31 – 1 取模之后的结果。

    Sample Input
    3 3
    1 2 2
    1 3 1
    2 3 1

    Sample Output
    2


    首先求出单源最短路,然后考虑第i个点,我们可以枚举1~i-1个点,求出dis[j]+g[i][j]=dis[i]的点,然后使用乘法原理即可。由于第i个点不可能由那些dis比它大的点转移过来,因此我们要开始按dis排序

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7fffffff
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e3,M=1e6,MOD=0x7fffffff;
    struct S1{
    	#define ls (p<<1)
    	#define rs (p<<1|1)
    	#define fa (p>>1)
    	struct node{
    		int x,v;
    		bool operator <(const node &a)const{return v<a.v;}
    	}Q[N*50+10];
    	int tot;
    	void insert(int x,int v){
    		Q[++tot]=(node){x,v};
    		int p=tot;
    		while (p!=1&&Q[p]<Q[fa])	swap(Q[p],Q[fa]),p=fa;
    	}
    	void Delete(){
    		Q[1]=Q[tot--];
    		int p=1,son;
    		while (ls<=tot){
    			if (rs>tot||Q[ls]<Q[rs])	son=ls;
    			else	son=rs;
    			if (Q[son]<Q[p])	swap(Q[p],Q[son]),p=son;
    			else	break;
    		}
    	}
    }Heap;
    int pre[(M<<1)+10],now[N+10],child[(M<<1)+10],val[(M<<1)+10],tot;
    int g[N+10][N+10],dis[N+10],ID[N+10];
    bool vis[N+10];
    void join(int x,int y,int z){pre[++tot]=now[x],now[x]=tot,child[tot]=y,val[tot]=z;}
    void insert(int x,int y,int z){join(x,y,z),join(y,x,z);}
    bool cmp(const int &x,const int &y){return dis[x]<dis[y];}
    void Dijkstra(int x){
    	memset(dis,63,sizeof(dis));
    	Heap.insert(x,dis[x]=0);
    	while (Heap.tot){
    		int Now=Heap.Q[1].x;
    		Heap.Delete();
    		if (vis[Now])	continue;
    		vis[Now]=1;
    		for (int p=now[Now],son=child[p];p;p=pre[p],son=child[p]){
    			if (dis[son]>dis[Now]+val[p]){
    				dis[son]=dis[Now]+val[p];
    				Heap.insert(son,dis[son]);
    			}
    		}
    	}
    }
    int main(){
    	int n=read(),m=read(),Ans=1;
    	memset(g,63,sizeof(g));
    	for (int i=1;i<=m;i++){
    		int x=read(),y=read(),z=read();
    		insert(x,y,z);
    		g[y][x]=g[x][y]=min(g[x][y],z);
    	}
    	for (int i=1;i<=n;i++)	g[i][i]=0,ID[i]=i;
    	Dijkstra(1);
    	sort(ID+1,ID+1+n,cmp);
    	for (int i=2;i<=n;i++){
    		int res=0;
    		for (int j=1;j<i;j++)
    			if (dis[ID[j]]+g[ID[i]][ID[j]]==dis[ID[i]])
    				res++;
    		Ans=1ll*Ans*res%MOD;
    	}
    	printf("%d
    ",Ans);
    	return 0;
    }
    
  • 相关阅读:
    python中使用cookies免登陆
    python中列表与元组的区别与转换
    python模块之mock
    python模块之Faker
    python模块之requests
    adb简单命令使用
    Mac下安装appium+python+Android sdk 环境完整流程
    git+pycharm结合使用
    github内的一些操作
    mac下git连接远程仓库gitee
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9745781.html
Copyright © 2011-2022 走看看