USACO 2.4.4 Bessie Come Home

带权边的Dijkstra

/*
ID: xjtuacm1
PROG: comehome
LANG: C++
*/
#include<iostream>
#include<stack>
#include<cstring>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
const int INF = 0x3f3f3f3f;
const int M = 10000;
const int N = 52;

// Graph structure
int n;
int to[M], nxt[M], head[N];
int w[M];
bool vis[N];
int e;
int dist[N]; // Distance array
struct cmp
{
    bool operator() (int a, int b)
    {
        return dist[a] > dist[b];
    }
};

void init()
{
    memset(vis, false, sizeof(vis));
    memset(head, -1, sizeof(head));
    e = 0;
}
void addEdge(int u, int v, int c)
{
    to[e] = v;
    nxt[e] = head[u];
    w[e] = c;
    head[u] = e++;
}

void addBiEdge(int u, int v, int c)
{
    addEdge(u, v, c);
    addEdge(v, u, c);
}

void dijkstra(int src)
{
    // Reset distance array
    memset(vis, false, sizeof(vis));
    for(int i = 0; i!= n; i++)
        dist[i] = INF;

    priority_queue<int, vector<int>, cmp> que;
    vis[src] = true;
    dist[src] = 0;
    que.push(src);
    int pnt = src;
    for(int i = 1; i!=n; i++)
    {
        for(int j = head[pnt]; j!= -1; j = nxt[j])
        {
            int v = to[j];
            if(!vis[v] && dist[pnt] + w[j] < dist[v])
            {
                dist[v] = dist[pnt] + w[j];
                que.push(v);
            }
        }
        while(!que.empty() && vis[que.top()])
            que.pop();
        if(que.empty())
            break;

        pnt = que.top(); que.pop();
        vis[pnt] = true;
    }
}

set<char> cows;
int r[N];
bool indirectCmp(int a, int b)
{
    return dist[a] < dist[b];
}

int toIdx(char ch)
{
    if(ch != tolower(ch))
        return ch - 'A';
    else
        return ch - 'a' + 26;
}
char toChar(int idx)
{
    if(idx < 26)
        return idx + 'A';
    else
        return idx - 26 + 'a';
}

int main(int argc, char *argv[])
{
    freopen("comehome.in", "r", stdin);
#ifndef USACO
    freopen("comehome.out", "w", stdout);
#endif // USACO

    int p;
    scanf("%d\n", &p);

    n = N;
    init();

    while(p--)
    {
        char f, t;
        int c;
        scanf("%c %c %d\n", &f, &t, &c);
        if(f == t)
            continue;

        bool flag = false;
        for(int edge = head[toIdx(f)]; edge != -1; edge = nxt[edge])
            if(to[edge] == (toIdx(t)))
        {
            w[edge] = min(w[edge], c);
            flag = true;
            break;
        }
        for(int edge = head[toIdx(t)]; edge != -1; edge = nxt[edge])
            if(to[edge] == (toIdx(f)))
        {
            w[edge] = min(w[edge], c);
            flag = true;
            break;
        }
        if(flag)
            continue;

        addBiEdge(toIdx(f), toIdx(t), c);
    }

    dijkstra(toIdx('Z'));

    for(int i = 0; i!= n; i++)
        r[i] = i;

    sort(r, r+n, indirectCmp);
    for(int i = 1; i!= n; i++)
    {
        if(r[i] < 26)
        {
            printf("%c %d\n", toChar(r[i]), dist[r[i]]);
            break;
        }
    }

    return 0;
}