GBX的Graph(最短路)
Problem B: Graph
Time Limit: 2 Sec Memory Limit: 128 MBSubmit: 1 Solved: 1
[Submit][Status][Web Board]
Description
There are n vertexs and m directed edges. Every vertex has a lowercase letters .Now, ZZT stand at 1.
he want to go to n to find ZZ.But ZZT dont like character strings "cnm" ,"tmd","nsb". so he won't walk such a continuous
3 vertex,the first vertex is 'c' second vertex is 'n' last vertex is 'm'; He wanted to find her as soon as possible.
Input
The first line in the input will contain the number of cases ,Each case begins with two integer n,m(2<=n<=100,m<=1000)
then follow a line contain a character string "a1a2a3a4a5...an" ai is the i vertex's lowercase letter.
then follow m line ,each line contain li,ri,ci , a edge connect li and ri cost time ci(1<=li,r1<=n,1<=ci<=100);
Output
for each case ,output a integer express the minimum time, if can't find ZZ output "-1"(without quotes);
Sample Input
1 4 4 cnmc 1 2 1 2 3 1 1 3 4 3 4 1
Sample Output
5
题意:给你一个n个点m条边的有向图,每个点都有一个小写字母。
如今ZZT站在点1。ZZ站在点n。ZZT想用最短的路程走到ZZ的地方。可是呢,ZZT不希望走过这种连续的三点:cnm,tmd,nsb。如今问你他是否能到达ZZ所在地。
若能,输出最短路径,否则输出-1。
分析:此题关键在于怎样构图。
我们能够把边当点来使用,那么总共同拥有m个点。
增加一个源点0连向以点1发出去的边,增加一个汇点m+1使得点全部指向点n的边连向点m+1,那么原题就变成了从点0開始到达点m+1的最短路径。构图时,当两条边(u,v)。(x,y)中 v == x 而且(str[u],str[v],str[y]) !=(c,n,m),(t,m,d),(n,s,b),则可连接。
构图完成。跑一遍最短路就可以。
题目链接:http://192.168.4.140/problem.php?
代码清单:
#include<set> #include<map> #include<cmath> #include<queue> #include<stack> #include<ctime> #include<cctype> #include<string> #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; typedef unsigned int uint; typedef unsigned long long ull; const int maxn = 100 + 5; const int maxv = 1000 + 5; const int max_dis=0x7f7f7f7f; struct Edge{ int to; int dis; Edge(){} Edge(int to,int dis){ this -> to = to; this -> dis = dis; } }; struct E{ int u,v,dis; }edge[maxv]; int T; int n,m; int a,b,c; bool vis[maxv]; int dist[maxv]; char str[maxn]; vector<Edge>graph[maxv]; void init(){ for(int i=0;i<maxv;i++) graph[i].clear(); } void input(){ scanf("%d%d%s",&n,&m,str); for(int i=1;i<=m;i++){ scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].dis); } } bool judge(int pre,int now,int to){ if(str[pre]=='c'&&str[now]=='n'&&str[to]=='m') return true; if(str[pre]=='t'&&str[now]=='m'&&str[to]=='d') return true; if(str[pre]=='n'&&str[now]=='s'&&str[to]=='b') return true; return false; } void createGraph(){ for(int i=1;i<=m;i++){ if(edge[i].u==1) graph[0].push_back(Edge(i,edge[i].dis)); if(edge[i].v==n) graph[i].push_back(Edge(m+1,0)); for(int j=1;j<=m;j++){ if(i==j) continue; if(edge[i].v==edge[j].u){ if(judge(edge[i].u-1,edge[i].v-1,edge[j].v-1)) continue; graph[i].push_back(Edge(j,edge[j].dis)); } } } } int spfa(){ memset(vis,false,sizeof(vis)); memset(dist,max_dis,sizeof(dist)); queue<int>q; while(!q.empty()) q.pop(); vis[0]=true; dist[0]=0; q.push(0); while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=false; for(int i=0;i<graph[u].size();i++){ int v=graph[u][i].to; int d=graph[u][i].dis; if(dist[v]>dist[u]+d){ dist[v]=dist[u]+d; if(!vis[v]){ vis[v]=true; q.push(v); } } } } if(dist[m+1]==max_dis) return -1; return dist[m+1]; } void solve(){ createGraph(); printf("%d\n",spfa()); } int main(){ // freopen("cin.txt","r",stdin); // freopen("cout.txt","w",stdout); scanf("%d",&T); while(T--){ init(); input(); solve(); }return 0; }