【ZJOI2017练习&UVA1057】D6T1 Routing(DP,SPFA)

题意:给你一个有向图, 并指定起点和终点。

问要从起点走向终点, 再从终点走向起点, 最少需要走过多少不同的节点。

对于 100%的数据, 有 N<=100, M<=min(1000,N*N)。 图中可能有重边或者自环

思路:

  1 const oo=700000000;
  2 var head1,head2,vet1,vet2,next1,next2:array[1..10000]of longint;
  3     q:array[0..100000]of record
  4                           x,y:longint;
  5                          end;
  6     dis,f:array[1..100,1..100]of longint;
  7     inq:array[1..100,1..100]of boolean;
  8     n,m,i,j,k,cas,tot1,tot2,x,y,z:longint;
  9
 10 function min(x,y:longint):longint;
 11 begin
 12  if x<y then exit(x);
 13  exit(y);
 14 end;
 15
 16 procedure spfa;
 17 var i,j,u1,u2,e1,e2,v1,v2,t,w,t1,w1,tmp:longint;
 18 begin
 19  for i:=1 to n do
 20   for j:=1 to n do
 21   begin
 22    inq[i,j]:=false;
 23    dis[i,j]:=oo;
 24   end;
 25  t:=0; w:=1; t1:=0; w1:=1;
 26  q[1].x:=1; q[1].y:=1; inq[1,1]:=true; dis[1,1]:=1;
 27  while t<w do
 28  begin
 29   inc(t); inc(t1);
 30   if t1=(n*n)<<1 then t1:=0;
 31   u1:=q[t1].x; u2:=q[t1].y; inq[u1,u2]:=false;
 32
 33   e1:=head1[u1];
 34   while e1<>0 do
 35   begin
 36    v1:=vet1[e1];
 37    tmp:=dis[u1,u2];
 38    if v1<>u2 then inc(tmp);
 39    if tmp<dis[v1,u2] then
 40    begin
 41     dis[v1,u2]:=tmp;
 42     if not inq[v1,u2] then
 43     begin
 44      inc(w); inc(w1);
 45      if w1=(n*n)<<1 then w1:=0;
 46      q[w1].x:=v1; q[w1].y:=u2; inq[v1,u2]:=true;
 47     end;
 48    end;
 49    e1:=next1[e1];
 50   end;
 51
 52   e2:=head2[u2];
 53   while e2<>0 do
 54   begin
 55    v2:=vet2[e2];
 56    tmp:=dis[u1,u2];
 57    if v2<>u1 then inc(tmp);
 58    if tmp<dis[u1,v2] then
 59    begin
 60     dis[u1,v2]:=tmp;
 61     if not inq[u1,v2] then
 62     begin
 63      inc(w); inc(w1);
 64      if w1=(n*n)<<1 then w1:=0;
 65      q[w1].x:=u1; q[w1].y:=v2; inq[u1,v2]:=true;
 66     end;
 67    end;
 68    e2:=next2[e2];
 69   end;
 70
 71
 72   if (u1<>u2)and(dis[u1,u2]+f[u1,u2]-1<dis[u2,u1]) then
 73   begin
 74    dis[u2,u1]:=dis[u1,u2]+f[u1,u2]-1;
 75    if not inq[u2,u1] then
 76    begin
 77     inc(w); inc(w1);
 78     if w1=(n*n)<<1 then w1:=0;
 79     q[w1].x:=u2; q[w1].y:=u1; inq[u2,u1]:=true;
 80    end;
 81   end;
 82  end;
 83 end;
 84
 85 procedure add1(a,b:longint);
 86 begin
 87  inc(tot1);
 88  next1[tot1]:=head1[a];
 89  vet1[tot1]:=b;
 90  head1[a]:=tot1;
 91 end;
 92
 93 procedure add2(a,b:longint);
 94 begin
 95  inc(tot2);
 96  next2[tot2]:=head2[a];
 97  vet2[tot2]:=b;
 98  head2[a]:=tot2;
 99 end;
100
101 begin
102  assign(input,‘uva1057.in‘); reset(input);
103  assign(output,‘uva1057.out‘); rewrite(output);
104  while not eof do
105  begin
106   read(n,m);
107   if n=0 then break;
108   for i:=1 to n do
109   begin
110    head1[i]:=0;
111    head2[i]:=0;
112   end;
113   tot1:=0; tot2:=0;
114   inc(cas);
115   writeln(‘Network ‘,cas);
116   for i:=1 to n do
117    for j:=1 to n do
118     if i<>j then f[i,j]:=oo;
119   for i:=1 to m do
120   begin
121    read(x,y);
122    f[x,y]:=1;
123    add1(x,y);
124    add2(y,x);
125   end;
126   for i:=1 to n do
127    for j:=1 to n do
128     for k:=1 to n do f[j,k]:=min(f[j,k],f[j,i]+f[i,k]);
129   if (f[1,2]=oo)or(f[2,1]=oo) then
130   begin
131    writeln(‘Impossible‘);
132    writeln;
133    continue;
134   end;
135   spfa;
136   writeln(‘Minimum number of nodes = ‘,dis[2,2]);
137   writeln;
138  end;
139  close(input);
140  close(output);
141 end.
时间: 2024-11-05 06:31:44

【ZJOI2017练习&UVA1057】D6T1 Routing(DP,SPFA)的相关文章

POJ 3182 The Grove [DP(spfa) 射线法]

题意: 给一个地图,给定起点和一块连续图形,走一圈围住这个图形求最小步数 本来是要做课件上一道$CF$题,先做一个简化版 只要保证图形有一个点在走出的多边形内就可以了 $hzc:$动态化静态的思想,假设已经有了路线怎么判断合法 点在多边形内是“点变多边形不变”,我们反过来维护多边形变 $f[i][j][0/1]$表示当前走到$(i,j)$,点是否在多边形内 维护一条向右发出的射线,每次走的时候看看有没有穿过射线就行了 因为这是个网格,我们可以规定只有从上面经过才算穿过 然后,这不是$DAG$啊怎

值得一做》关于一道DP+SPFA的题 BZOJ1003 (BZOJ第一页计划) (easy+)

这是一道数据范围和评测时间水的可怕的题,只是思路有点难想,BUT假如你的思路清晰,完全了解怎么该做,那就算你写一个反LLL和反SLE都能A,如此水的一道题,你不心动吗? 下面贴出题目 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输路线,让货物能够按时到达目的地

HDU 4284 状压dp+spfa堆优化

题意: 给定n个点 m条无向边 d元. 下面m行表示每条边 u<=>v 以及花费 w 下面top 下面top行 num c d 表示点标为num的城市 工资为c 健康证价格为d 目标是经过给定的top个城市,当到达该城市时,必须马上购买该城市的健康证并打工赚钱(每个城市只打工1次) 问从1城市出发,最后回到1城市,能否收集到所有的健康证 思路: 由于top很小,所以状压dp dp[i][tmp]表示当前处于i点 经过城市的状态为tmp时 身上最多的钱. 首先对dis数组floyd 跑出最短路,

HDU 4085 Peach Blossom Spring 斯坦纳树 状态压缩DP+SPFA

状态压缩dp+spfa解斯坦纳树 枚举子树的形态 dp[i][j] = min(dp[i][j], dp[i][k]+dp[i][l]) 其中k和l是对j的一个划分 按照边进行松弛 dp[i][j] = min(dp[i][j], dp[i'][j]+w[i][j])其中i和i'之间有边相连 #include <cstdio> #include <cstring> #include <queue> using namespace std; const int maxn

hdu1224 dp spfa

dp: 1 //Accepted 300 KB 15 ms 2 //dp时用到了a[n+1]可是一直没把她赋值,WA了无数次 3 //dp[i]=max(dp[j]+a[i]) j<i map[j][i]=1 4 #include <cstdio> 5 #include <cstring> 6 #include <iostream> 7 using namespace std; 8 const int imax_n = 105; 9 const int inf =

POJ2686 Traveling by Stagecoach(状压DP+SPFA)

题目大概是给一张有向图,有n张票,每张票只能使用一次,使用一张票就能用pi匹马拉着走过图上的一条边,走过去花的时间是边权/pi,问从a点走到b点的最少时间是多少. 用dp[u][S]表示当前在u点且用过的票集合是S的最少时间,丢进SPFA更新. 1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 using namespace std; 5 #define INF 1e8 6 #define MAXN 3

【BZOJ 2595】2595: [Wc2008]游览计划 (状压DP+spfa,斯坦纳树?)

2595: [Wc2008]游览计划 Time Limit: 10 Sec  Memory Limit: 256 MBSec  Special JudgeSubmit: 1572  Solved: 739 Description Input 第一行有两个整数,N和 M,描述方块的数目. 接下来 N行, 每行有 M 个非负整数, 如果该整数为 0, 则该方块为一个景点:否则表示控制该方块至少需要的志愿者数目. 相邻的整数用 (若干个) 空格隔开,行首行末也可能有多余的空格. Output 由 N

ZOJ1027 Travelling Fee(DP+SPFA)

给一张有向无环图,边都有花费,从某点到某点走的那条路径上的那一条花费最多的边可以省掉,问从起点到终点的最少花费的多少, 往DP想的话,就可以写出这个状态dp[u][mx],表示到达u点已经省掉的花费为mx的最少花费. 用SPFA更新转移方程..或者理解成队列+我为人人的转移..其实这题这样子也能解有环图. 看了别人博客,发现还有三种解法: 枚举每一条边作为省掉的边,n次SPFA.这方法简洁,可惜想不出= = 跑Dijkstra,根据记录到每一点时的最长边更新,正确性不懂.. Floyd+DP:加

HDU3768 Shopping(状态压缩DP+spfa)旅行商问题

Shopping Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 577    Accepted Submission(s): 197 Problem Description You have just moved into a new apartment and have a long list of items you need