FZU2271【Folyd】

传送门: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的指针。

猜你喜欢

转载自blog.csdn.net/weixin_40317006/article/details/81556860