la resolución de codeforces 1206D ciclo más corto Floyd informe no figura mínimo aro.

codeforces 1206D ciclo más corto informe de resolución de problemas

Ideas de resolución de problemas: con el algoritmo de Floyd, sin embargo n gran tiempo de espera, por lo que para optimizar el pensamiento, log2 (10 ^ 18) < 60, sabemos que n elementos en
el cajón n-1, debe haber por lo menos el número de elementos en un cajón > = 2, siempre que el n-> 120, debe haber un elemento de cajón 3, es decir, capaz de anillo, n algoritmo de Floyd luego determina a 120 o menos en la línea. Nota: ignorar todas las entradas 0, mientras que INF no es demasiado grande, este 0x3f3f3f3f tres juntos se rompe como el rango de datos int.
Aquí Insertar imagen Descripción

#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#include<vector>
#pragma warning(disable:4996)
#define INF 300
#define ll long long
#define PI acos(-1.0)
const int N = 200010;
const int maxn = 1e5 + 10;
using namespace std;
int dp[130][130], dis[130][130];
ll a[maxn];
bool cmp(ll a, ll b)
{
	return a > b;
}
int main()
{
	int n;
	scanf("%d", &n);
	int cnt = 0;
	ll tem;
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &tem);
		if (tem)
		{
			cnt++;
			a[cnt] = tem;
		}
	}
	if (cnt > 120)
	{
		printf("3\n");
		return 0;
	}
	else if (cnt < 3)
	{
		printf("-1\n");
		return 0;
	}
	n = cnt;
	sort(a + 1, a + cnt + 1, cmp);
	for (int i = 1; i <= cnt; i++)//初始化所有边
	{
		for (int j = i+1; j <= cnt; j++)
		{
			if (a[i] & a[j])
			{
				dp[j][i] = dp[i][j] =1;
			}
			else
			{
				dp[j][i] = dp[i][j] = INF;
			}
		}
	}
	for (int i = 1; i <= cnt; i++)
	{
		for (int j = 1; j <= cnt; j++)
		{
			dis[i][j] = dp[i][j];
		}
	}
	int ans = INF;
	for (int k = 1; k <= cnt; k++)
	{
		for (int i = 1; i < k; i++)
		{
			for (int j = i + 1; j < k; j++)
			{
				ans = min(ans, dis[i][j] + dp[i][k] + dp[k][j]);//这里INF大了就爆了
			}
		}
		for (int i = 1; i <= cnt; i++)
		{
			for (int j = 1; j <= cnt; j++)
			{
				dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);//更新i到j需要经过的边数
			}
		}
	}
	if (ans == INF)
		printf("-1\n");
	else
		printf("%d\n", ans);
	return 0;
}



Publicado 64 artículos originales · ganado elogios 0 · Vistas 1442

Supongo que te gusta

Origin blog.csdn.net/weixin_45566331/article/details/104937010
Recomendado
Clasificación