传送门:http://acm.fzu.edu.cn/problem.php?pid=2271
【分析】题目主要是输出关闭的道路编号。有两种删除情况:①删除重边,也就是A->B有多条边,肯定留下最小那条。②如果A->B的路径长度大于等于A->C->D->B,那么 留下经过路径多的那条,删除A-->B。
#include<iostream>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
const int M = 0x3f3f3f3f;
int map[100 + 10][100 + 10];
int mmap[100 + 10][100 + 10];
int vis[100 + 10][100 + 10];
int main()
{
int t;
scanf("%d", &t);
for (int c = 1; c <= t; c++)
{
memset(mmap, 0, sizeof(mmap));
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
map[i][j] = M;
}
}
int sum = 0;
for (int i = 1; i <= m; i++)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if (map[a][b] < M)
sum++; //情况一
if (c < map[a][b])
map[a][b] = map[b][a] = c;
}
memcpy(mmap, map, sizeof(mmap));
memset(vis, 0, sizeof(vis));
for (int k = 1; k <= n; k++)
{
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (map[i][j]>=map[i][k] + map[k][j] && i != j)
{
map[i][j] = map[i][k] + map[k][j];
vis[i][j] = 1; //情况二
}
}
}
}
for (int i = 1; i < n; i++)
{
for (int j = i + 1; j <= n; j++)
{
if (vis[i][j] && map[i][j] <= mmap[i][j] && mmap[i][j] < M)
sum++; //情况二
}
}
printf("Case %d: %d\n", c, sum);
}
}
顺便提一下memcpy函数的用法https://blog.csdn.net/qq_35040828/article/details/71123521
头文件:#include <string.h>
原型: extern void *memcpy(void *dest, void *src, unsigned int count);
说明: src和dest所指内存区域不能重叠,函数返回指向dest的指针。