牛客IOI周赛27-普及组 D 旅游
题意:
给定一张图,只有当起点和终点都满足条件时才可以连边,给定多次询问,求最短路
思路:
几乎Floyed 裸题,但是由于之前没怎么做过Floyed的题导致熟练度不够一开始想着用dij + 理解错题意两次(经典)导致没能写出来。
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<math.h>
#include<queue>
using namespace std;
typedef long long ll;
typedef double dd;
typedef pair<int, int> pii;
typedef pair<dd, dd> pdd;
const int MAXN = 310;
const int inf = 1e9 + 7;
const int MAXM = 8000010;
int n, m, s, q;
int dis[MAXN][MAXN];
int xd[MAXN];
void f(int x)
{
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= n;j++)
{
dis[i][j] = min(dis[i][j], dis[i][x] + dis[x][j]);
}
}
}
int main()
{
memset(dis, 0x3f, sizeof(dis));
int mx = dis[1][1];
scanf("%d%d%d%d", &n, &m, &s, &q);
for (int i = 1;i <= n;i++) dis[i][i] = 0;
xd[s] = 1;
for (int i = 1;i <= m;i++)
{
int u, v, w;
scanf("%d%d%d", &u, &v, &w);
dis[u][v] = min(dis[u][v], w);
}
f(s);
while (q--)
{
int c, x;
scanf("%d%d", &c, &x);
if (c == 1)
{
if (!xd[x]) f(x);
xd[x] = 1;
}
else
{
if (xd[x] == 0 || dis[s][x] == mx)
{
printf("-1\n");
continue;
}
else
{
printf("%d\n", dis[s][x]);
s = x;
}
}
}
}