zoukankan      html  css  js  c++  java
  • [UVa1057] Routing

    问题描述

    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
    ",++t);
    		if(dis[1][2]>=inf||dis[2][1]>=inf){
    			puts("Impossible");
    			puts("");
    			continue;
    		}
    		Dijkstra();
    		printf("Minimum number of nodes = %d
    ",f[2][2]);
    		puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    深入理解CSS中的层叠上下文和层叠顺序
    利用CSS3制作淡入淡出动画效果
    <link>标签的rel属性全解析
    解决<pre>标签里的文本换行(兼容IE, FF和Opera等)
    HTML特殊字符大全
    清除浮动4种方法总结下
    打开wamp中的phpmyadmin出现403的错误
    js访问CSS最终计算样式
    js 正则 exec() 和 match() 数据抽取
    函数表达式中,函数名称在函数体内是只读的
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11677078.html
Copyright © 2011-2022 走看看