JSOI重要的城市

2021-09-30 11:43:29 字數 1412 閱讀 3984

【題目描述】

給出n個城市,m條道路以及道路的權值,這樣的城市是重要的:如果乙個城市c被破壞後,存在兩個不同城市a,b(a,b均不等於c),a,b間的距離增長(或不通),則城市c為重要的。

按遞增次序列出所有重要城市的編號。(若無重要城市,輸出"no important cities.")

【樣例】

city.in

4 4             //n,m

1 2 1         //s t len:城市s到城市t間存在一條長度為len的道路

2 3 1

4 1 2

4 3 2

city.out

【限制】

n,m<=200,len<=10000

1s【問題分析】

暴力演算法:

floyed求出任意兩個城市間最初的最短距離,再列舉被破壞的點,floyed判斷是否有城市間的距離增長(或不通)

時間複雜度:o(n^4)

dijkstra:

對源點s進行d演算法,在拓展的時候可以求出每個節點的前驅,若前驅唯一,則說明從s到此節點必然經過前驅,故前驅為重要城市。

但上述演算法求出的重要城市都是s到i最短路徑上與i直接相連的,是否會有遺漏呢?

若果s到i的最短路徑(s->k1->k2...kp->kp+1..i)上有重要城市kp不與i直接相連,則kp必為s到kp+1的最短路的必經點。此時kp與kp+1直接相連,可以被確定為重要的。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define maxn 210 #define oo 2000010 using namespace std; typedef long long ll; int min(int x,int y) floyd1(); int ok=0; for(int i=1;i<=n;i++) if(floyd(i)) if(!ok) printf("no important cities."); } //n次dijstra,記錄更新每個節點可用的前驅結點個數,以及第乙個前驅結點,擴充套件時判斷該節點是否被唯一更新 vector

g[maxn],w[maxn]; int times[maxn],pre[maxn]; bool vis[maxn]; void init() } bool done[maxn]; int d[maxn]; void relax(int u,int v,int c) int first=1,ok=0; for(int i=1;i<=n;i++)if(vis[i]) if(!ok) printf("no important cities."); } int main()

JSOI2007 重要的城市

題目描述 參加jsoi冬令營的同學最近發現,由於南航校內修路截斷了原來通向計算中心的路,導致去的路程比原先增加了近一公里。而食堂門前施工雖然也截斷了原來通向計算中心的路,卻沒有使路程增加,因為可以找到同樣長度的路作替代。其實,問題的關鍵在於,路截斷的地方是交通要點。同樣的情況也出現在城市間的交通中。...

JSOI2007 重要的城市 x

開始 腦殘ing 誒?暴力能過 噼里啪啦碼碼碼 tle tle 啥?看錯複雜度?帶個25的常數 floyd,並記錄兩點間的乙個重要的城市。當出現等距離最短路時說明上該點上次的鬆弛點 並非唯一 刪去否則更新 include include include const int maxn 287 inli...

洛谷 1841 JSOI2007 重要的城市

部落格觀賞效果更佳 給你乙個聯通的無向簡單圖,請你求出有多少個點滿足 刪除之後,存在兩點最短路增長了。點數 200 200 2 00。這個在某種程度上告訴了你這題用什麼演算法 博主注 一邊f lo yd floyd floy d一遍記錄即珂。恕我直言,這簡直是剛學flo yd floyd floy ...