 /**//*
一个无向图,n<=3000 , m <= 20000
有k个限制,表示a->b->c不能走, k<= 10^5
求1到n的最短路,不能走过有限制的地方

我猜是bfs,但是不会做,我的思维局限在状态是在顶点上,这样是不够记录的
如a->b->a,两个a的状态值是不同的

看了watashi的,DIY群上有人说是以边为状态
dp[pre][now]表示从1到pre->now这条边经过的花费
枚举now的非限制的邻接边扩展
对于判重问题通过去掉边来做
it = E[u].erase(it)
这样下次就不会走了 神奇丫!!!!!!!!!!!!

存限制时是用map<pair<int,int>,set<int> > mp
这样存(a,b,c)比起弄两个pair好多了!!!
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<list>
#include<set>

using namespace std;

const int MAXN = 10086;
const int INF = 1000000000;

list<short> E[3001];
map<pair<short,short> , set<short> > mp;//(a,b,c)
int dp[3001][3001] ;
short pre[3001][3001];

 void print(int last , int now) {
if(last == -1)return;
print(pre[last][now] , last);
printf("%d ",last);
}

int main()
  {
 for(int n , m, k;~scanf("%d%d%d",&n,&m,&k);) {
 for(int i = 1 ; i <= n; i ++) {
E[i].clear();
}
int a,b,c;
 for(int i = 0 ; i < m ; i++) {
scanf("%d%d",&a,&b);
E[a].push_back(b);
E[b].push_back(a);
}
mp.clear();
 for(int i = 0 ; i < k ; i++) {
scanf("%d%d%d",&a,&b,&c);
mp[make_pair(a,b)].insert(c);
}

fill(dp[1],dp[n+1],INF);

queue<pair<short,short> > Q;
 for(list<short>::iterator it = E[1].begin() ; it != E[1].end() ; it++) {
dp[1][*it] = 1;
pre[1][*it] = -1;
Q.push(make_pair(1,*it));
}
E[1].clear();
 while(!Q.empty()) {
pair<short,short> p = Q.front();
Q.pop();
a = p.first;
b = p.second;
set<short> &iset = mp[p];
 for(list<short>::iterator it = E[b].begin() ; it != E[b].end();) {
 if(iset.count(*it) > 0) {
it++;
}
 else {
dp[b][*it] = dp[a][b] + 1;
pre[b][*it] = a;
Q.push(make_pair(b,*it));
it = E[b].erase(it);//处理判重!!
}
}
}
int ans = INF , ansPre;
 for(int i = 1 ; i < n ; i++) {
 if(dp[i][n] < ans) {
ans = dp[i][n];
ansPre = i;
}
}

if(ans == INF)puts("-1");
 else {
printf("%d\n",ans);
print(ansPre,n);
printf("%d\n",n);
}
}
return 0;
}
|
|
常用链接
随笔分类
Links
搜索
最新评论

|
|