NOIP 2012 文化之旅

洛谷 P1078 文化之旅

洛谷传送门

JDOJ 1788: [NOIP2012]文化之旅 T4

JDOJ传送门

Description

img

Input

img

Output

img

Sample Input

Input I: 2 2 1 1 2 1 2 0 1 1 0 1 2 10 Input II: 2 2 1 1 2 1 2 0 1 0 0 1 2 10

Sample Output

Output I: -1 Output II: 10

HINT

img

Source

NOIP2012普及组

题解:

NOIP2012普及组的文化之旅后来被证明是一道错题。

所以就用了一种错误的解法(仅供参考):

输入之后如果文化排斥就不建边,这样就保证了最短路的更新不必考虑到它。

最后特判一下如果两个城市文化一样就直接输出-1.

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
int n,k,m,s,t;
int culture[101];
int divide[101][101];
int map[101][101];
int dist[101],v[101];
priority_queue<pair<int,int> >q;
void dijkstra(int s)
{
    memset(dist,INF,sizeof(dist));
    memset(v,0,sizeof(v));
    dist[s]=0;
    q.push(make_pair(0,s));
    while(!q.empty())
    {
        int x=q.top().second;
        if(v[x])
        {
            q.pop();
            continue;
        }
        x=q.top().second,q.pop();v[x]=1;
        for(int i=1;i<=n;i++)
            if(dist[i]>dist[x]+map[x][i])
            {
                dist[i]=dist[x]+map[x][i];
                q.push(make_pair(-dist[i],i));
            }
    }
}
int main()
{
    scanf("%d%d%d%d%d",&n,&k,&m,&s,&t);
    for(int i=1;i<=n;i++)
        scanf("%d",&culture[i]);
    for(int i=1;i<=k;i++)
        for(int j=1;j<=k;j++)
            scanf("%d",&divide[i][j]);
    memset(map,INF,sizeof(map));
    for(int i=1;i<=m;i++)
    {
        int u,v,d;
        scanf("%d%d%d",&u,&v,&d);
        if(divide[culture[u]][culture[v]]==0)
            map[u][v]=min(map[u][v],d);
        if(divide[culture[v]][culture[u]]==0)
            map[v][u]=min(map[v][u],d);
    }
    dijkstra(s);
    if(dist[t]>1000000000 || culture[s]==culture[t])
    {
        puts("-1");
        return 0;
    }
    printf("%d",dist[t]);
    return 0;
}
原文地址:https://www.cnblogs.com/fusiwei/p/11824451.html