题目描述
从前,在一个王国中,在n个城市间有m条道路连接,而且任意两个城市之间至多有一条道路直接相连。在经过一次严重的战争之后,有d条道路被破坏了。国王想要修复国家的道路系统,现在有两个重要城市A和B之间的交通中断,国王希望尽快的恢复两个城市之间的连接。你的任务就是修复一些道路使A与B之间的连接恢复,并要求修复的道路长度最小。
输入输出格式
输入格式:
输入文件road.in,第一行为一个整数n(2<n≤100),表示城市的个数。这些城市编号从1到n。第二行为一个整数m(n-1≤m≤n(n-1)/2),表示道路的数目。接下来的m行,每行3个整数i,j,k(1≤i,j≤n,i≠j,0<k≤100),表示城市i与j之间有一条长为k的道路相连。
接下来一行为一个整数d(1≤d≤m),表示战后被破坏的道路的数目。在接下来的d行中,每行两个整数i和j,表示城市i与j之间直接相连的道路被破坏。
最后一行为两个整数A和B,代表需要恢复交通的两个重要城市。
输出格式:
输出文件road.out,仅一个整数,表示恢复A与B间的交通需要修复的道路总长度的最小值。
输入输出样例
#include <ext/pb_ds/priority_queue.hpp> #include <iostream> #include <cstdio> #define N 10005 #define pa pair<int,int> #define inf 0x3f3f3f3f using namespace std; using namespace __gnu_pbds; typedef __gnu_pbds::priority_queue<pa,greater<pa>,pairing_heap_tag>heap; heap::point_iterator id[N]; int n,m,d,cnt,S,T,to[N<<1],far[N],head[N],nextt[N<<1],val[N<<1],f[105][105]; inline void ins(int u,int v,int w) { nextt[++cnt]=head[u];to[cnt]=v;val[cnt]=w; head[u]=cnt; } void dijkstra() { heap q; for(int i=1;i<=n;++i) far[i]=inf; far[S]=0; id[S]=q.push(make_pair(0,S)); for(int u;!q.empty();) { u=q.top().second;q.pop(); for(int i=head[u];i;i=nextt[i]) { int v=to[i]; if(far[v]>far[u]+val[i]) { far[v]=far[u]+val[i]; if(id[v]!=0) q.modify(id[v],make_pair(far[v],v)); else id[v]=q.push(make_pair(far[v],v)); } } } } int main(int argc,char *argv[]) { scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) f[i][j]=(i!=j)*inf; for(int x,y,z;m--;) { scanf("%d%d%d",&x,&y,&z); f[x][y]=f[y][x]=z; } scanf("%d",&d); for(int x,y;d--;) { scanf("%d%d",&x,&y); f[x][y]*=-1;f[y][x]*=-1; } for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) { if(f[i][j]>=0&&f[i][j]!=inf) ins(i,j,0); else if(f[i][j]<0) ins(i,j,f[i][j]*(-1)); } scanf("%d%d",&S,&T); dijkstra(); printf("%d\n",far[T]); return 0; }