• hihoCoder #1379 Emulator


    hihoCoder Challenge 23, Prob. A
    时间限制:5000ms
    单点时限:1000ms
    内存限制:256MB

    描述

    有一个$n$个点的无向正权图$G$,这个图是连通的,小Y知道这些点两两之间的最短路的长度。

    小J想要构造一个新的无向正权图$G'$,使得新图中两两之间的最短路的长度与原图一样,并且边数最少。

    输入

    第一行一个整数$n$,表示点的个数。

    接下来$n$行,每行$n$个整数。第$i$行第$j$个整数表示$i$点到$j$点的在$G$中的最短路长度,保证合法。

    $1le n le 300$,保证图$G$中最短路长度不超过$10^9$。

    输出

    一个整数表示新图$G'$的最小的边数。

    样例输入

    4
    0 1 3 6
    1 0 2 5
    3 2 0 3
    6 5 3 0

    样例输出

    3


    Solution

    这道题现场卡住了.
    首先由题目描述可知原图$G$是连通图.
    设$G=G(V,E)$, 现在不知道边集$E$, 只知道最短路矩阵$D$.

    先考虑一个简化问题:

    对于某条给定的边$(u,v)$, 能否从最短路矩阵判断它是否必需 ("必需"即一定存在于原图中), 如果能, 如何判断?

    能. 判断方法: 判断是否 $exists x in V setminus$ ${u, v}$使得$D_{u,v}=D_{u,x}+D_{x,v}$.
    证明:
    $forall (u,v) in E$, 用$w(u,v)$表示边$(u,v)$的长度. 显然$w(u,v) ge D_{u,v}$. 又依题意, $forall (u,v), w(u,v)>0$.
    $D_{u,v}=D_{u,x}+D_{x,v}$ $Longrightarrow w(u,v) < D_{u,x}, w(u, v) < D_{x, v}$.

    $Longrightarrow u o x, x o v$ 的最短路都一定不包含边 $(u,v)$. (这好像很显然:))
    这样就可以放心地将边$(u,v)$从图$G$中删除, 而最短路矩阵不变.

    这样就可以得出一个迭代的算法. 而且可以推出:

    对于给定的最短路矩阵$D$, 与之对应的边数最少的图是唯一的.

    思维链条:

    某条边$(u,v)$是否必需由最短路矩阵$D$唯一确定 $ o$ 删去非必需的边后最短路矩阵$D$不变 $ o$ 删掉的边是"独立"的, 互不影响.
    删边的独立性直白地说即是:只有当图$G$中存在一条能替代$(u,v)$这条边的路径时才把$(u,v)$删除。

    Implementation

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=305;
    
    int d[N][N];
    
    int main(){
    	int n;
    	cin>>n;
    	for(int i=0; i<n; i++)
    		for(int j=0; j<n; j++)
    			cin>>d[i][j];
    
    	int res=n*(n-1)/2;
    
    	for(int i=0; i<n; i++)
    		for(int j=i+1; j<n; j++){
    				for(int k=0; k<n; k++){
    					if(k!=i && k!=j && d[i][j]==d[i][k]+d[k][j]){
    						--res;
    						break;
    					}
    				}			
    		}
    
    	cout<<res<<endl;
    	return 0;
    }
    
  • 相关阅读:
    nodejs获取服务器数据到页面
    Struts 2
    JQuery
    JDBC
    Hiberbate
    EasyUi
    JavaScript
    利用 HashSet 去过滤元素是否重复
    HTML
    MySQL
  • 原文地址:https://www.cnblogs.com/Patt/p/6001451.html
Copyright © 2020-2023  润新知