信息奥赛一本通1486: CH 6202 黑暗城堡 最短路径生成树计数
1486:黑暗城堡
【題目描述】
知道黑暗城堡有 N 個房間,M 條可以制造的雙向通道,以及每條通道的長度。
城堡是樹形的并且滿足下面的條件:
設 Di為如果所有的通道都被修建,第 i 號房間與第 1 號房間的最短路徑長度;
而 Si 為實際修建的樹形城堡中第 i 號房間與第 1 號房間的路徑長度;
要求對于所有整數 i(1≤i≤N),有 Si=Di 成立。
你想知道有多少種不同的城堡修建方案。當然,你只需要輸出答案對 231?1 取模之后的結果就行了。
【輸入】
第一行為兩個由空格隔開的整數 N,M;
第二行到第 M+1 行為 3 個由空格隔開的整數 x,y,l:表示 x 號房間與 y 號房間之間的通道長度為 l。
【輸出】
一個整數:不同的城堡修建方案數對 231?1 取模之后的結果。
【輸入樣例】
4 6
1 2 1
1 3 2
1 4 3
2 3 1
2 4 2
3 4 1
【輸出樣例】
6
【提示】
樣例說明
一共有 4 個房間,6 條道路,其中 1 號和 2 號,1 號和 3 號,1 號和 4 號,2 號和 3 號,2 號和 4 號,3 號和 4 號房間之間的通道長度分別為 1,2,3,1,2,1。
而不同的城堡修建方案數對 231?1 取模之后的結果為 6。
數據范圍:
對于全部數據,1≤N≤1000,1≤M≤N(N?1)2,1≤l≤200。
#include<iostream> #include<cstring> #include<sstream> #include<cstdio> #include<algorithm> #include<queue> using namespace std; #define read(x) scanf("%lld",&x) #define Read(x,y) scanf("%lld%lld",&x,&y) #define gc(x) scanf(" %c",&x); #define mmt(x,y) memset(x,y,sizeof x) #define write(x) printf("%d\n",x) #define INF 0x3f3f3f3f #define ll long long #define mod ((1LL<<31) - 1LL) const ll N = 1005; const ll M = 1e6; ll d[N]; bool vis[N];ll id[N]; ll head[N],tot; ll w[N][N]; struct Edge {ll next;ll to;ll dis; }edge[M*2]; inline void add(ll from,ll to,ll dis) {edge[++tot].next = head[from];edge[tot].to = to;edge[tot].dis = dis;head[from] = tot; } void spfa() {mmt(d,0x3f);mmt(vis,0);d[1] = 0;queue<ll> Q;Q.push(1);vis[1] = 1;while(Q.size()){ll x= Q.front();Q.pop();vis[x] = 0;for(ll i = head[x];~i;i = edge[i].next){ll y = edge[i].to;ll dis = edge[i].dis;if(d[y] > d[x] + dis){d[y] = d[x ]+dis;if(!vis[y]){vis[y] = 1;Q.push(y);}}}} } bool cmp(ll a,ll b) {return d[a] < d[b]; } void init() {mmt(head,-1);tot = 0;for(int i = 1;i <=1000;++i){for(int j = 1;j <= 1000;++j){w[i][j] = INF;}w[i][i] = 0;} } int main() {init();ll n,m;ll f,t,dis;Read(n,m);for(ll i = 1;i <= m;++i){Read(f,t);read(dis);if(w[f][t] > dis) w[f][t] = w[t][f] = dis;add(f,t,dis);add(t,f,dis);}spfa();//先跑一次最短路,求出d數組 dijkstra也可以for(ll i = 1;i <= n;++i) id[i] = i;sort(id +1 ,id + n+1,cmp);//按d[ ]從小到大排序ll ans = 1;ll cnt = 0;for(ll i = 2;i <= n;++i){cnt = 0;for(ll j = 1;j <= i-1;++j){//模擬最短路徑樹形成的過程,并按乘法原理統計方案數,if(d[id[i]] == d[id[j]] + w[id[j]][id[i]]) cnt ++;}ans = ans * cnt %mod;}cout<<ans<<endl; }總結
以上是生活随笔為你收集整理的信息奥赛一本通1486: CH 6202 黑暗城堡 最短路径生成树计数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bug是什么意思(网络用语bug是什么意
- 下一篇: 真相:中国版BBB用USB连电脑没有盘符