zoukankan      html  css  js  c++  java
  • loj黑暗城堡

    黑暗城堡

    题目描述
    你知道黑暗城堡有(N)个房间,M 条可以制造的双向通道,以及每条通道的长度。
    城堡是树形的并且满足下面的条件:
    (D_i)为如果所有的通道都被修建,第i号房间与第1号房间的最短路径长度;
    (S_i)为实际修建的树形城堡中第i号房间与第1号房间的路径长度;
    要求对于所有整数(i(1<= i <= N)),有(S_i = D_i)成立。
    你想知道有多少种不同的城堡修建方案。当然,你只需要输出答案对(2 ^ {31} - 1)取模之后的结果就行了。
    输入格式
    第一行为两个由空格隔开的整数 ;
    第二行到第n + 1行为3个由空格隔开的整数x,y,l:表示x号房间与y号房间之间的通道长度为l。
    输出格式
    一个整数:不同的城堡修建方案数对(2 ^ {31} - 1)取模之后的结果。

    题解:首先dij,求出1号点到其他点的最短距离。
    然后扫描所有边,如果dis[v]==dis[u]+e[i].w,说明让v点的距离为给最短距离的路径又多了一条,所以,cnt[v]++;
    最终结果就是所有点的cnt[]相乘。

    #include <cstdio>
    #include <iostream>
    #include <queue> 
    #define orz cout << "AK IOI"
    
    using namespace std;
    const int maxn = 1010;
    const int maxm = 500010;
    const int mod = 2e31 - 1;
    
    inline int read()
    {
    	int x = 0, f = 1;
    	char ch = getchar();
    	while (ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
    	while (ch >= '0' && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}
    	return x * f;
    }
    int n, m, dis[maxn], vis[maxn], cnt[maxn];
    long long ans = 1;
    struct edge{
    	int u, v, w, nxt;
    }e[maxm << 1];
    int head[maxn], js;
    void add(int u, int v, int w)
    {
    	e[++js].u = u;
    	e[js].v = v;
    	e[js].w = w;
    	e[js].nxt = head[u];
    	head[u] = js;
    }
    struct node{
    	int w, now;
    	bool operator < (const node &x)const
    	{
    		return w > x.w;
    	}
    };
    priority_queue<node> q;
    void dijkstra(int s)
    {
    	for(int i = 1; i <= n; i++)
    	dis[i] = 0x7fffffff;
    	dis[s] = 0;
    	q.push((node{0, s}));
    	while(!q.empty())
    	{
    		node t = q.top();
    		q.pop();
    		int u = t.now;
    		if(vis[u]) continue;
    		vis[u] = 1;
    		for(int i = head[u]; i; i = e[i].nxt)
    	    {
    	    	int v = e[i].v;
    	    	if(dis[v] > dis[u] + e[i].w)
    	    	{
    	    		dis[v] = dis[u] + e[i].w;
    				q.push((node{dis[v], v})); 
    			}
    		}
    	}
    }
    int main()
    {
        n = read(), m = read();
        for(int i = 1; i <= m; i++)
        {
        	int u = read(), v = read(), w = read();
        	add(u, v, w);
        	add(v, u, w);
    	}
    	dijkstra(1);
    	/*for(int i = 1; i <= n; i++)
    	printf("%d ",dis[i]);*/
    	for(int i = 1; i <= n; i++)
    	   for(int j = head[i]; j; j = e[j].nxt)
    	   {
    	   	  int v = e[j].v;
    	  	  if(dis[v] == dis[i] + e[j].w) 
    		  cnt[v]++;
    	   } 
    	for(int i = 2; i <= n; i++)
    	ans = ans * cnt[i] % mod;
    	printf("%lld",ans);
    	return 0;
    }
    
  • 相关阅读:
    MySQL表的完整性约束
    MySQL支持的数据类型
    MySQL表操作
    MySQL存储引擎概述
    onblur和onkeyup事件
    Web控件LinkButton
    jQuery防止中文乱码
    jQuery 动态添加、删除css样式
    VS2012生成Web时报未能找到元数据文件xxx.dll
    单击EasyUI的datagrid行时不选中
  • 原文地址:https://www.cnblogs.com/yangchengcheng/p/14213119.html
Copyright © 2011-2022 走看看