文化之旅

原题链接:https://www.luogu.org/problemnew/show/1078#sub

今天想写图论。

气得要死,在洛谷一直都是60,说我RE,我下载下来数据本地评测可以过。。

在隔壁codevs上A了。。。

这题其实就是一个裸的最短路,只不过需要判定文化排斥问题。

所以只需要在求最短路的同时维护一下当前文化就好。

参考代码:

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <queue>
 5 #define maxn 2333
 6 #define INF 2147483647
 7 using namespace std;
 8 inline int read(){
 9     int num = 0;
10     char c;
11     while (( c=getchar()) == ' ' || c =='\n' || c == 'r');
12     num = c - '0';
13     while (isdigit(c = getchar()))
14         num = num * 10 + c - '0';
15     return num;
16 }
17 struct Edge{
18     int from,to,dis;
19 };
20 struct node{
21     int point;
22     int culture;
23 };
24 Edge edge[maxn];
25 int head[maxn];
26 int dis[maxn];
27 int tot = 0;
28 int n,k,m,s,t;
29 int u,v,d;
30 int refuse[maxn][maxn];
31 int c[maxn];
32 void add_edge(int from,int to, int dis){
33     edge[++tot].from = head[from];
34     edge[tot].to = to;
35     edge[tot].dis = dis;
36     head[from] = tot;
37 }
38 bool inq[maxn];
39 void spfa(){
40     memset(inq,false,sizeof(inq));
41     for (int i=1;i<=n;i++)
42         dis[i] = INF;
43     dis[s] = 0;
44     queue<node> q;
45     node st;
46     st.point = s;
47     st.culture = c[s];
48     q.push(st);
49     inq[st.point]= true;
50     while (!q.empty()){
51         node u = q.front();
52         q.pop();
53         inq[u.point] = false;
54         for (int i = head[u.point];i;i = edge[i].from){
55             int v = edge[i].to;
56             int w = edge[i].dis;
57             if (refuse[c[v]][u.culture])
58                 continue;
59             else{
60                 if (dis[u.point] + w < dis[v]){
61                     dis[v] = w + dis[u.point];
62                     if (!inq[v]){
63                         inq[v] = true;
64                         node nextp;
65                         nextp.culture = c[v];
66                         nextp.point = v;
67                         q.push(nextp);
68                     }
69                 }
70             }
71         }
72     }
73 }
74 int main(){
75     n = read();k = read();m = read();s = read();t = read();
76     for (register int i=1;i<=n;i++)
77         c[i] = read();
78     for (register int i=1;i<=k;i++)
79         for (register int j=1;j<=k;j++)
80             refuse[i][j] = read();
81     for (register int i=1;i<=m;i++){
82         u = read();v = read();d = read();
83         add_edge(u,v,d);
84         add_edge(v,u,d);
85     }
86     spfa();
87     if (dis[t] == INF)
88         printf("-1");
89     else
90         printf("%d",dis[t]);
91     return 0;
92 }

 

posted @ 2017-10-24 21:14  ShawnZhou_Aether  阅读(181)  评论(0编辑  收藏  举报