代码改变世界

[pat]A1072 Gas Station

2018-08-30 16:48  legend聪  阅读(299)  评论(0编辑  收藏  举报

这道题的结点编号是字符串类型,处理的过程很有意思,用getID将house和GasStation进行区分

#include<bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int maxn = 1020;
int G[maxn][maxn];
int d[maxn];
int n, m, k, ds;
bool vis[maxn] = {false};
double optSum = INF;
double optDis = 0;
int opt = -1;
int getID(string str)
{
    int ID = 0;
    int i = 0;
    int len = str.length();
    while (i < len)
    {
        if (str[i] != 'G')
        {
            ID = 10 * ID + str[i] - '0';
        }
        i++;
    }
    if (str[0] != 'G')
    {
        return ID;
    }
    else
        return ID + n;
}
void dj(int s)
{
    d[s] = 0;
    int i;
    for (i = 0; i < n + m; i++)
    {
        int u = -1, MIN = INF;
        int j;
        for (j = 1; j <= n + m; j++)
        {
            if (vis[j]==false&&d[j]<MIN)
            {
                u = j;
                MIN = d[j];
            }
        }
        if (u == -1)
            return;
        vis[u] = true;
        int v;
        for (v = 1; v <= n + m; v++)
        {
            if (vis[v] == false&&G[u][v]!=INF)
            {
                if (d[v] > d[u] + G[u][v])
                {
                    d[v] = d[u] + G[u][v];
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d%d%d", &n, &m, &k, &ds);
    int i = 0;
    fill(G[0], G[0] + maxn*maxn, INF);
    fill(d, d + maxn, INF);
    for (i = 0; i < k; i++)
    {
        string str1, str2;
        cin >> str1 >> str2;
        int st, ed;
        st = getID(str1);
        ed = getID(str2);
        scanf("%d", &G[st][ed]);
        G[ed][st] = G[st][ed];
    }
    for (i = 1; i <= m; i++)
    {
        memset(vis, false, sizeof(vis));
        fill(d, d + maxn, INF);
        dj(n + i);//松弛完成
        int j;
        double sum = 0;
        double minDis = INF;
        int flag = 1;
        for (j = 1; j <= n; j++)//遍历n个house
        {
            if (d[j] <=ds)//必须能覆盖到位
            {
                sum += d[j];
                if (minDis > d[j])
                {
                    minDis = d[j];
                }
            }
            else
            {
                flag = 0;
                break;
            }
        }
        if (flag == 1)
        {
            if (minDis > optDis)
            {
                optDis = minDis;
                optSum = sum;
                opt = n+i;
            }
            else if (minDis == optDis&&sum < optSum)
            {
                optSum = sum;
                opt = n + i;
            }
        }
    }
    if (opt == -1)
    {
        printf("No Solution\n");
    }
    else
    {
        printf("G");
        printf("%d\n", opt -n);
        printf("%.1f ", optDis);
        printf("%.1f", optSum / n);
    }
}