习题:破坏基地(最短路+计数)

破坏基地(tyvj2040)

描述

在Z国和W国之间一直战火不断。
好不容易,W国的间谍把完整的Z国的军事基地的地图到手了。
于是W国决定再次出击,一举击破Z国的防线。
W国认真研究了Z国的地形,发现Z国有N个军事基地,我们不妨编号成1..N,而且经过深刻研究,发现1号军事基地是资源补给基地,而N号军事基地是前线。
由于地形的缘故,只有M对军事基地两两可达,当然是有距离的。
此时W国的弹头紧缺,当下的弹头只能去毁灭一个军事基地。当然了,最重要的就是毁灭一个军事基地,使得资源补给基地与前线的最短距离发生变化。但是Z国也不是白痴,他们的资源补给基地与前线有着极高的防御力,所以W国只能去炸掉其余的N-2个基地,当然炸掉某个基地后,这个基地就不可达了。
于是问题就来了,炸掉哪些基地后会使得资源补给基地与前线的最短距离发生变化呢?
注:假若炸掉某个基地后,1号基地和N号基地不连通,那么我们也认为他们的最短距离发生了变化。

输入格式

输入数据第一行是两个正整数N,M,意义如题所述。
接下来M行,每行包括三个正整数x,y,d,表示有一条边连接x、y两个地点,其距离为d。
数据保证图是连通的。

输出格式

输出数据的第一行包含一个整数K,表示有K个基地可毁灭,且毁灭其中任意一个后,资源补给基地与前线的最短距离发生变化。
接下来K行,每行输出一个军事基地的编号,要求编号递增。
在wyl8899神犇的率领下,W国必胜!!!
因此一定不会存在K=0的情况。

测试样例1

输入

6 7
1 2 3
1 5 2
2 3 5
2 4 3
2 5 4
2 6 5
3 4 2
输出

1
2
备注

对于30%的数据,N<=100,M<=1,000;
对于60%的数据,N<=2,000,M<=20,000;
对于100%的数据,N<=10,000,M<=100,000,1<=d<=10,000;

分析:

图中可能存在多条最短路,显然当某个点在所有最短路上才是应选择的点。

于是我们分别从1和n求一次最短路,并统计从1到各点最短路条数f1和n到各点最短路条数f2,dis1[i]+dis2[i]=minlen,f1[i]*f2[i]=1到n最短路条数 说明i在所有最短路上,加入答案就行了。

代码:

program hehe;
type
  point=^node;
   node=record
      x,v:int64; next:point;
   end;

var
  a:array[0..10000]of point;
  q:array[0..100000]of int64;
  dis,u,tot,r,b:array[0..10000]of int64;
  g:array[0..10000]of boolean;
  n,i,m,x,y,ans:longint; len,v:int64;
procedure add(x,y,v:longint);
var p:point;
begin
  new(p); p^.x:=y; p^.v:=v; p^.next:=a[x]; a[x]:=p;
end;
procedure spfa(s:longint);
var i,x,y,h,t:longint; p:point;
begin
  for i:=1 to n do begin dis[i]:=maxlongint*10; g[i]:=false; tot[i]:=0;end;
  g[s]:=true; dis[s]:=0; tot[s]:=1; h:=0; t:=1;  q[t]:=s;
  while h<t do
   begin
     inc(h); x:=q[h]; new(p); p:=a[x]; g[x]:=false;
     while p<>nil do
      begin
        y:=p^.x;
        if dis[x]+p^.v<dis[y] then
        begin
         dis[y]:=dis[x]+p^.v; tot[y]:=tot[x];
         if g[y]=false then
          begin
            inc(t); q[t]:=y; g[y]:=true;
          end;
        end
        else if dis[x]+p^.v=dis[y] then
         begin
           inc(tot[y],tot[x]);
           if g[y]=false then
           begin
            inc(t); q[t]:=y; g[y]:=true;
          end;
         end;
        p:=p^.next;
      end;
   end;
  if s=1 then
   begin len:=dis[n]; u:=dis; r:=tot;end;
end;
begin
  readln(n,m);
  for i:=1 to m do
   begin
     readln(x,y,v);
     add(x,y,v); add(y,x,v);
   end;
  spfa(1); spfa(n);
  for i:=1 to n do
   if (i<>1)and(i<>n) then
   if u[i]+dis[i]=len then if tot[i]*r[i]=tot[1] then begin inc(ans);b[ans]:=i; end;
  writeln(ans);
  for i:=1 to ans do writeln(b[i]);
end.

时间: 2024-10-13 04:52:27

习题:破坏基地(最短路+计数)的相关文章

习题:最短路计数(SPFA最短路计数)

最短路计数(洛谷1144)题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条.输入输出格式输入格式:输入第一行包含2个正整数N,M,为图的顶点数与边数.接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边.输出格式:输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可.如果无法到达顶点i则输出0.输入输出样例输

HDU 1491 社交网络(最短路计数)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1491 题意:给出一个联通的无向图,边有权值.定义I(v)如下,计算每个点的I值. 思路:(1)最简单的就是那个floyd了...g[i][j]记录最短路长度,f[i][j]记录个数,不多说了: (2)下面说说我自己想出来的算法..枚举s和t,计算每个点到s和t的最短路..然后建立最短路树..之后求s到t的最短路个数..然后枚举删掉某个点再求最短路个数,则差值即为通过删掉点的最短路数目.

洛谷P1144 最短路计数(SPFA)

To 洛谷.1144 最短路计数 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M,为图的顶点数与边数. 接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边. 输出格式: 输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可.如果无法到达顶点i则输

洛谷 1144 最短路计数 bfs

洛谷1144 最短路计数 传送门 其实这道题目的正解应该是spfa里面加一些处理,,然而,,然而,,既然它是无权图,,那么就直接bfs了,用一个cnt记录一下每一个点的方案数,分几种情况讨论一下转移,最后输出cnt即为结果.. 题目中所说的重边和自环啥的没看出来有啥影响.. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 const int maxn = 100000 + 500;

【SPFA】 最短路计数

最短路计数 [问题描述]   给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. [输入格式]   输入第一行包含2个正整数N,M,为图的顶点数与边数. 接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边. [输出格式]   输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的结果即可.如果无法到达顶点i则输出0. [输入样

最短路与次短路计数

poj  3464  http://poj.org/problem?id=3463 问最短路的条数+比最短路权值大 1  的条数 做法  比较一下次短路和最短路的值  若次短路恰好比最短路大1,答案为最短路+次短路条数,否则答案就是最短路条数 1 #include<cstdio> 2 const int inf=0x3f3f3f3f; 3 class Count_short_path { ///最短路与次短路计数Dijkstra_o(MV^2) 4 typedef int typec;///边

洛谷P1144 最短路计数 及其引申思考

图论题目练得比较少,发一道spfa的板子题目- 题目:P1144 题目描述 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. 输入输出格式 输入格式: 输入第一行包含2个正整数N,M,为图的顶点数与边数. 接下来M行,每行两个正整数x, y,表示有一条顶点x连向顶点y的边,请注意可能有自环与重边. 输出格式: 输出包括N行,每行一个非负整数,第i行输出从顶点1到顶点i有多少条不同的最短路,由于答案有可能会很大,你只需要输出mod 100003后的

题解——[JSOI2007]重要的城市 floyd:最短路计数

---题面--- 题解: 其实感觉还是比较妙的,第一眼看题想到floyd统计最短路条数, 注意到对于任意两点x,y而言,floyd将会枚举其最短路所可能经过的所有中转点, 因此我们可以直接分别统计对于所有二元组而言,最短路上必须经过的中转点, 最后遍历一次所有统计到的结果,并用bool数组标记一个地点是否被作为过中转点 最后再遍历一次bool数组,如果是中转点就输出即可 注意有多条最短路并不一定意味着这两个点之间的最短路就没有关键点, 因为这几条最短路可能有一个(或多个)共同用点,这时共同用点将

[图论]最短路计数(spfa)

最短路计数 Description 给出一个NN个顶点MM条边的无向无权图,顶点编号为1-N1−N.问从顶点11开始,到其他每个点的最短路有几条. Input 第一行包含22个正整数N,MN,M,为图的顶点数与边数. 接下来MM行,每行22个正整数x,yx,y,表示有一条顶点xx连向顶点yy的边,请注意可能有自环与重边. output 共NN行,每行一个非负整数,第ii行输出从顶点11到顶点ii有多少条不同的最短路,由于答案有可能会很大,你只需要输出ans \bmod 100003ansmod1