a國有n座城市,依次標為1到n。同時,在這n座城市間有m條單向道路,每條道路的長度是乙個正整數。現在,a國交通部指定了一條從城市1到城市n的路徑,並且保證這條路徑的長度是所有從城市1到城市n的路徑中最短的。不幸的是,因為從城市1到城市n旅行的人越來越多,這條由交通部指定的路徑經常發生堵塞。現在a國想知道,這條路徑中的任意一條道路無法通行時,由城市1到n的最短路徑長度是多少。
輸入格式:
輸入檔案第一行是三個用空格分開的正整數n、m和l,分別表示城市數目、單向道路數目和交通部指定的最短路徑包含多少條道路。按下來m行,每行三個用空格分開的整數a、b和c,表示存在一條由城市a到城市b的長度為c的單向道路。這m行的行號也是對應道路的編號,即其中第1行對應的道路編號為1,第2行對應的道路編號為2,...,第m行對應的道路編號為m。最後一行為l個用空格分開的整數sp(1)...,,sp(l),依次表示從城市1到城市n的由交通部指定的最短路徑上的道路的編號。
輸出格式:
輸出檔案包含l行,每行為乙個整數,第i行(i=1,2...,,l)的整數表示刪去編號為sp(i)的道路後從城市1到城市n的最短路徑長度。如果去掉後沒有從城市1到城市n的路徑,則輸出一1。
輸入樣例#1:
4 5 21 2 2
1 3 2
3 4 4
3 2 1
2 4 3
1 5
輸出樣例#1:
66
100%的資料滿足2題解:
玄學大火題,有這樣乙個結論:
去掉最短路上的一條邊後,那麼現在的最短路一定是 先沿原最短路走一段->再繞原非最短路走一端->再走回原最短路.
所以我們就可以開始亂搞,從1開始列舉刪除最短路上的邊,然後用該邊的左端點,在斷掉該邊後,去鬆弛原最短路上編號大於該點的點,
然後答案就是f[u]+last[u] (last[u]為u到n的最短路) 注意此題f陣列不需要清空,然後我們就把f[u]+last[u]加入堆中,然後每一組詢問我們先刪除不合法的點(u在最短路上的編號小於當前邊左端點編號),然後當前的堆頂就是答案,堆為空就是-1
1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 #include 8using
namespace
std;
9const
int n=100005,m=200005;10
intgi()
16int n,m,ps,num=0
,head[n];
17struct
lina[m];
20void init(int x,int y,int dis,int
ids)
23struct
edgee[m];
26struct
node
31};
32 priority_queuest;
33int last[n],imp[m],f[n],q[n*10],mod=n*10,id[n];bool
vis[n],mark[n];
34void spfa(int
k)35
);47}48
if(!vis[u] && !mark[u])52}
53}54 vis[x]=false;55
}56}57
void
work()
5864
for(int i=1;i<=ps;i++)imp[i]=gi(),id[e[imp[i]].y]=id[e[imp[i]].x]+1;65
for(int i=ps;i>=1;i--)
69int
x,y;
70 memset(f,127/3,sizeof(f));f[1]=0;71
for(int i=1;i<=ps;i++)80}
81}82int
main()
83
HNOI2014 道路堵塞
a國有n座城市,依次標為1到n。同時,在這n座城市間有m條單向道路,每條道路的長度是乙個正整數。現在,a國交通部指定了一條從城市1到城市n的路徑,並且保證這條路徑的長度是所有從城市1到城市n的路徑中最短的。不幸的是,因為從城市1到城市n旅行的人越來越多,這條由交通部指定的路徑經常發生堵塞。現在a國想...
HNOI2014 道路堵塞 最短路,線段樹
對不起對不起,辣雞蒟蒻又來用核彈打蚊子了 完全ignore了題目給出的最短路,手工搞出乙個最短路,發現對答案沒什麼影響 所以乾脆轉化為經典問題 每次詢問刪掉一條邊後的最短路 如果刪掉的是非最短路邊,那麼顯然毫無影響 如果刪掉的是最短路邊,那麼我們倒過來,考慮這個時候每條非最短路邊的貢獻。對於一條非最...
bzoj3575 Hnoi2014 道路堵塞
一開始看錯題啦!某一條邊不走的最短路相當於1 沿最短路 x y 沿最短路 n,於是 定義t,表示從起點到最短路上序號r有一條長度為l的非最短路。然後用堆維護即可。慎用memset。tle。include include include include include define n 100005 ...