NOI 2007 소셜네트워크서비스(COGS 15) Floyd 최단거리 및 시나리오 수

1667 단어
자신의 DP가 정말 약하다는 것을 발견하고 오늘 오전부터 지금까지 AC 몇 개의 DP 문제가 없었습니다. 그리고 다른 문제를 써서 자신감을 높이기로 결정했습니다.TAT
이 문제는 주로 플로이드 구안 수를 고찰한다.
먼저 두 개의 점이 서로 도달할 수 있도록 보장하는 그림에서 f[i][j]를 설정하면 i에서 j 사이의 가장 짧은 경로의 개수를 표시하고 초치는 1이다.Floyd에서 최단로를 구하는 과정에서 d[i][k]+d[k][j]가 있으면
이 문제는 거의 누드 문제에 가깝다. 그 다음에 3층 순환을 써서 제목이 제시한 공식에 따라 각 점의 중요한 값을 구하면 된다.
주의해야 할 것은 출력이 부점형수이기 때문에 계산하는 과정은 d와 f수조로 계산하기 때문에 d와 f를 모두 부점형으로 성명하는 것이 가장 좋다. 그렇지 않으면 계산할 때 강제 유형 전환을 사용하는 것은 믿을 수 없다.
#include 
#include 
#include 
#define inf 1e20
using namespace std;

int n, m;
double imp[101], d[101][101], f[101][101];

int main()
{
	freopen("network1.in","r",stdin);
	freopen("network1.out","w",stdout);	
	
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i++)
	for(int j = 1; j <= n; j++){
		f[i][j] = 1;
		d[i][j] = inf;
	}
	for(int i = 1; i <= m; i++){
		int a, b;
		double c;
		scanf("%d %d %lf", &a, &b, &c);
		d[a][b] = d[b][a] = c;
	}

	for(int k = 1; k <= n; k++)
	for(int i = 1; i <= n; i++)
	for(int j = 1; j <= n; j++){
		if(k == i || i == j || k == j) continue;
		if(d[i][k]+d[k][j] < d[i][j]){
			d[i][j] = d[i][k]+d[k][j];
			f[i][j] = f[i][k]*f[k][j];
		}else if(d[i][k]+d[k][j] == d[i][j]) 
			f[i][j] += f[i][k]*f[k][j];
	}
	
	for(int s = 1; s <= n; s++)
	for(int t = 1; t <= n; t++)
	for(int i = 1; i <= n; i++){
		if(s == i || t == i || s == t) continue;
		if(d[s][i]+d[i][t] == d[s][t])
		imp[i] += (f[s][i]*f[i][t])/f[s][t];
	}
	
	for(int i = 1; i <= n; i++)
		printf("%.3lf
", imp[i]); }

좋은 웹페이지 즐겨찾기