Fzu2271 X

题意:一个图n个点m条边,(n<100)问最多能删除几条边使得两两城市的距离不变

题解:先处理出n*n的矩阵,对于每一条边能删除说明这条边能由其他边进行替代,那么只要枚举中间点就可以知道这条边是不是多余的,

这个过程和Floyd的过程很像

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string.h>
#define INF 0x3f3f3f3f
#define maxn 110
using namespace std;
struct edge{
    int from, to, w;
};
vector<edge>edges;
int T, ans, n, ca = 1, m, a, b, w, mp[maxn][maxn];
int main(){
    scanf("%d", &T);
    while(T--){
        ans = 0;
        memset(mp, INF, sizeof(mp));
        edges.clear();
        scanf("%d%d", &n, &m);
        for(int i=0;i<m;i++){
            scanf("%d%d%d", &a, &b, &w);
            if(mp[a][b] != INF) ans++;
            if(mp[a][b] >=  w)
                mp[a][b] = mp[b][a] = w;
        }
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++)
                if(mp[i][j] != INF) edges.push_back((edge){i, j, mp[i][j]});
            mp[i][i] = 0;
        }
        for(int k=1;k<=n;k++)
            for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                mp[i][j] = min(mp[i][k]+mp[k][j], mp[i][j]);
        for(int i=0;i<edges.size();i++){
            edge e = edges[i];
            if(mp[e.from][e.to] < e.w) ans++;
            else if(mp[e.from][e.to] == e.w){
                int flag = 0;
                for(int k=1;k<=n;k++){
                    if(e.to != k&&e.from!=k&&mp[e.from][k]+mp[k][e.to] == e.w){
                        flag = 1;
                        break;

                    }
                }
                if(flag == 1) ans++;
            }

        }
        printf("Case %d: ", ca++);
        printf("%d
", ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Noevon/p/8927086.html