此题是河南省第八届acm C题 点击打开链接
比赛时写这道题由于学长给了一种奇葩的建图方式 导致浪费了两个小时去写搜索 当然最终也没有过这道题 后来和老板他们讨论 说起配合的问题 说不应该先听队友的思路 否则容易被先入为主 没有别的想法 在轻院已经吃亏 由于长期缺乏组队经验 我并没有意识到改正 正确的应该自己也看下题 想想自己的思路 然后和队友去讨论
当时的建图方法是 是 a b c d 然后 a b 一条变 权值为1 然后 b c 1 c d 1 然而对于这样的奇葩建图方式我并没有产生任何的怀疑 后来下场自己想想实际都觉的可笑 单程公交线 怎么不应该这样建图 正确的建图方法 应该是 a 到 b c d 各有一条权值为1的边 然后是 b 到 c d c 到d 只要建好图 直接求最短路即可
听人说这道题是原题 其实 图论里面的基本知识只是在大一匆匆学习了一下 知道有那么回事 所以很难以灵活运用 不会变形使用 还是需要把基础算法学牢 不要贪多
重点就是建图 建好图直接dijkstra 求最短路 floyd会超时
另外郑州oj上的数据仍旧有误 好像已经修正了 但是样例的数据还是错的
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstring>
#include <cstdio>
#include <vector>
#include <string>
#include <iterator>
#include <cmath>
#include <deque>
#include <stack>
#include <cctype>
#include <iomanip>
using namespace std;
typedef long long ll;
typedef long double ld;
const int N = 510;
const int INF = 0xfffffff;
const double EPS = 1e-8;
const ll MOD = 1e9 + 7;
const ld PI = acos (-1.0);
#define INFL 0x7fffffffffffffffLL
#define met(a, b) memset(a, b, sizeof(a))
#define put(a) cout << setiosflags(ios::fixed) << setprecision(a)
int g[N][N], vis[N], dis[N];
void dijkstra (int n);
int main ()
{
int n, m, t;
scanf ("%d", &t);
while (t--)
{
scanf ("%d%d", &m, &n);
for (int i=0; i<=n; i++)
for (int j=0; j<=n; j++)
g[i][j] = INF;
for (int i=0; i<m; i++)
{
char ch;
int temp[N], k = 0;
while (true)
{
scanf ("%d%c", &temp[k++], &ch);
if (ch == '\n') break;
}
for (int j=0; j<k; j++)
{
for (int k1=j; k1<k; k1++)
{
int x1 = temp[j], y1 = temp[k1];
g[x1][y1] = 1;
}
}
}
dijkstra (n);
if (dis[n] != INF) printf("%d\n", dis[n] - 1);
else puts("NO");
}
return 0;
}
void dijkstra (int n)
{
met (vis, 0); vis[1] = 1;
for (int i=1; i<=n; i++)
dis[i] = g[1][i];
for (int i=0; i<=n; i++)
{
int u = 0, minx = INF;
for (int j=0; j<=n; j++)
{
if (!vis[j] && minx > dis[j])
u = j, minx = dis[j];
}
vis[u] = 1;
for (int j=0; j<=n; j++)
{
if (!vis[j] && dis[j] > g[u][j] + dis[u])
dis[j] = g[u][j] + dis[u];
}
}
}