问题描述

As more and more transactions between companies and people are being carried out electronically over

the Internet, secure communications have become an important concern. The Internet Cryptographic

Protocol Company (ICPC) specializes in secure business-to-business transactions carried out over a

network. The system developed by ICPC is peculiar in the way it is deployed in the network.

A network like the Internet can be modeled as a directed graph: nodes represent machines or routers,

and edges correspond to direct connections, where data can be transmitted along the direction of an

edge. For two nodes to communicate, they have to transmit their data along directed paths from the

first node to the second, and from the second node to the first.

Figure: An arrow from node X to node Y means that it is possible to connect to node Y from node X

but not vice versa. If software is installed on nodes 1, 2, 7, and 8, then communication is possible

between node 1 and node 2. Other configurations are also possible but this is the minimum cost

option. This figure corresponds to the first sample input.

To perform a secure transaction, ICPC’s system requires the installation of their software not only

on the two endnodes that want to communicate, but also on all intermediate nodes on the two paths

connecting the end-nodes. Since ICPC charges customers according to how many copies of their software

have to be installed, it would be interesting to have a program that for any network and end-node pair

finds the cheapest way to connect the nodes.

输入格式

The input consists of several descriptions of networks. The first line of each description contains two

integers N and M (2 ≤ N ≤ 100), the number of nodes and edges in the network, respectively.

The nodes in the network are labeled 1, 2, . . . , N, where nodes 1 and 2 are the ones that want to

communicate. The first line of the description is followed by M lines containing two integers X and Y

(1 ≤ X, Y ≤ N), denoting that there is a directed edge from X to Y in the network.

The last description is followed by a line containing two zeroes.

输出格式

For each network description in the input, display its number in the sequence of descriptions. Then

display the minimum number of nodes on which the software has to be installed, such that there is

a directed path from node 1 to node 2 using only the nodes with the software, and also a path from

node 2 to node 1 with the same property. (Note that a node can be on both paths but a path need not

contain all the nodes.) The count should include nodes 1 and 2.

If node 1 and 2 cannot communicate, display ‘IMPOSSIBLE’ instead.

Follow the format in the sample given below, and display a blank line after each test case.

样例输入

8 12

1 3

3 4

4 2

2 5

5 6

6 1

1 7

7 1

8 7

7 8

8 2

2 8

2 1

1 2

0 0

样例输出

Network 1

Minimum number of nodes = 4

Network 2

IMPOSSIBLE

题目大意

n 个点m条边, 从点1走到点2再走回去, 求最少经过多少个不同的点. (n<=100)

解析

可以把经过1和2的环拆成从1出发到2的路径和从2到1的路径。如果我们建立原图的反图,那么就是求正图上从1出发到2的路径和反图上从1出发到2的路径最少经过的不同的点。这个可以利用动态规划加最短路的思想。设状态\(f[i][j]\)表示正图上到i、反图上到j经过的最少的不同点个数。转移时用Dijkstra最短路的形式,在正图和反图上分别沿着当前点的边扩展一次,如果更新就放进队列当中。有如下转移方程:

\[f[u1][v]=f[u1][u2]+[u1!=v],((u2,v)\in E2)\\
f[v][u2]=f[u1][u2]+[u2!=v],((u1,v)\in E1)
\]

但是,我们会发现,某些情况下\(f[i][j]\)的值会比实际情况多。对于这种有偏差的情况,我们可以换一种转移的方式。通过观察,发现这种情况下,\(f[i][j]\)是由\(f[j][i]\)多走j到i的最短路得到的。因此,我们有

\[f[u2][u1]=min(f[u2][u1],f[u1][u2]+dis[u1][u2]-1)
\]

\(dis[i][j]\)表示i到j的最短路,可用Floyd求出。注意,如果不是特殊情况,\(f[u1][u2]+dis[u1][u2]-1\)会得到错误的答案。所以要去最小值。

代码

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
#define N 102
#define M 10002
using namespace std;
const int inf=0x3f3f3f3f;
struct node{
int x1,x2,d;
node(int _x1,int _x2,int _d){
x1=_x1;x2=_x2;d=_d;
}
};
bool operator < (node a,node b) { return a.d>b.d; }
int head1[N],ver1[M*2],nxt1[M*2],l1;
int head2[N],ver2[M*2],nxt2[M*2],l2;
int t,n,m,i,j,k,f[N][N],dis[N][N];
int read()
{
char c=getchar();
int w=0;
while(c<'0'||c>'9') c=getchar();
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w;
}
void insert1(int x,int y)
{
l1++;
ver1[l1]=y;
nxt1[l1]=head1[x];
head1[x]=l1;
}
void insert2(int x,int y)
{
l2++;
ver2[l2]=y;
nxt2[l2]=head2[x];
head2[x]=l2;
}
void Dijkstra()
{
priority_queue<node> q;
memset(f,0x3f,sizeof(f));
f[1][1]=1;
q.push(node(1,1,1));
while(!q.empty()){
int x1=q.top().x1,x2=q.top().x2,d=q.top().d;
q.pop();
if(d!=f[x1][x2]) continue;
for(int i=head1[x1];i;i=nxt1[i]){
int y=ver1[i],w=(x2!=y);
if(d+w<f[y][x2]){
f[y][x2]=d+w;
q.push(node(y,x2,f[y][x2]));
}
}
for(int i=head2[x2];i;i=nxt2[i]){
int y=ver2[i],w=(x1!=y);
if(d+w<f[x1][y]){
f[x1][y]=d+w;
q.push(node(x1,y,f[x1][y]));
}
}
if(x1!=x2&&d+dis[x1][x2]-1<f[x2][x1]){
f[x2][x1]=d+dis[x1][x2]-1;
q.push(node(x2,x1,f[x2][x1]));
}
}
}
int main()
{
while(1){
n=read();m=read();
if(n==0&&m==0) break;
memset(head1,0,sizeof(head1));
memset(head2,0,sizeof(head2));
memset(dis,0x3f,sizeof(dis));
l1=l2=0;
for(i=1;i<=m;i++){
int u=read(),v=read();
insert1(u,v);
insert2(v,u);
dis[u][v]=1;
}
for(k=1;k<=n;k++){
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(dis[i][j]>dis[i][k]+dis[k][j]) dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
printf("Network %d\n",++t);
if(dis[1][2]>=inf||dis[2][1]>=inf){
puts("Impossible");
puts("");
continue;
}
Dijkstra();
printf("Minimum number of nodes = %d\n",f[2][2]);
puts("");
}
return 0;
}

最新文章

  1. Hibernate中事务声明
  2. 【Tomcat】配置Tomcat
  3. 10、技术经理要阅读的书籍 - IT软件人员书籍系列文章
  4. js运动框架 step by step
  5. X64相关文章
  6. windows远程桌面3389超时锁定时间调整方法(取消锁屏时间限制)
  7. 【Android - 进阶】之事件分发机制
  8. javascript时间函数
  9. Python基础之变量作用域
  10. windows 8.1 cmd命名提示符全屏
  11. Nginx配置:nginx如何配置跳转fpm
  12. Ionic3多个自定义过滤器--管道(pipe)
  13. edu9E. Thief in a Shop
  14. HTML前期学习总结
  15. Shell教程 之流程控制
  16. JAVA每日一旅2
  17. linux 的常用命令---------第一阶段
  18. HDU2888 Check Corners(二维RMQ)
  19. DNS之XX记录
  20. Loadrunner socket协议lrs_receive函数接收到返回数据包 仍然等待服务器返回--解决

热门文章

  1. Windows环境下Mysql 5.7读写分离简单记录
  2. Jmeter之仅一次控制器
  3. mysql5.7无法启动原因排查
  4. Eclipse 添加 UML Model插件
  5. myBatis 基于javaBean配置
  6. 红帽学习笔记[RHCSA] 第五课[用户、权限相关]
  7. Linux 系统多台主机之间做SSH免密码登陆
  8. sql limit order by and where
  9. spark性能调优03-shuffle调优
  10. RouteReuseStrategy angular路由复用策略详解,深度刨析路由复用策略