BOJ 333 最小生成树+最短路

来源:互联网 发布:socket accept 端口 编辑:程序博客网 时间:2024/05/22 23:03

很裸的一个题吧,就是先求出一个最小生成树,然后求的同时把图给建好,然后枚举起点,求最短路。因为在树上求最短路必然是O(n)的,所以总的复杂度是O(n2)的

求最短路的时候囧了,直接写的SPFA,其实直接BFS就行了。不过明显写SPFA写习惯了。

当然这道题卡人的地方很猥琐,是精度。

用double竟然精度都不够,很诧异啊,然后经指点才知道,题目说最多有两位小数,直接放大100倍成long long类型的就行了,而且不能用double直接乘100,会挂,可以用字符串读入,然后处理,或者加个eps,然后输出的时候也没什么要求,其实就三种情况,整数,1个小数,二个小数。判断一下就行了。

/*ID: sdj22251PROG: inflateLANG: C++*/#include <iostream>#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <cstring>#include <cmath>#include <ctime>#define MAXN 1105#define INF 10000000000000000LL#define L(x) x<<1#define R(x) x<<1|1#define PI acos(-1.0)#define eps 1e-7using namespace std;long long dis[MAXN][MAXN];long long lowcost[MAXN], d[MAXN];int nearvex[MAXN], head[MAXN], vis[MAXN], q[MAXN * MAXN];int n, m, e;struct node{    int v, next;    long long w;}edge[2 * MAXN * MAXN];void insert(int x, int y, long long w){    edge[e].v = y;    edge[e].w = w;    edge[e].next = head[x];    head[x] = e++;}void spfa(int src){    for(int i = 1; i <= n; i++)        d[i] = INF;    int h = 0, t = 1;    memset(vis, 0, sizeof(vis));    d[src] = 0;    q[0] = src;    vis[src] = 1;    while(h < t)    {        int u = q[h++];        vis[u] = 0;        for(int i = head[u]; i != -1; i = edge[i].next)        {            int v = edge[i].v;            long long w = edge[i].w;            if(d[v] > d[u] + w)            {                d[v] = d[u] + w;                if(!vis[v])                {                    q[t++] = v;                    vis[v] = 1;                }            }        }    }}void out(long long x){    if(x % 100 == 0)  cout << x / 100 << endl;    else if(x % 10 == 0) cout << x / 100 << '.' << x / 10 % 10 << endl;    else cout << x / 100 << '.' << x % 100 << endl;}void prim(int u){    long long sumweight = 0;    for(int i = 1; i <= n; i++)    {        lowcost[i] = dis[u][i];        nearvex[i] = u;    }    nearvex[u] = -1;    for(int i = 1; i < n; i++)    {        long long mi = INF;        int v = -1;        for(int j = 1; j <= n; j++)        {            if(nearvex[j] != -1 && lowcost[j] < mi)            {                v = j; mi = lowcost[j];            }        }            if(v != -1)            {                insert(nearvex[v], v, lowcost[v]);                insert(v, nearvex[v], lowcost[v]);                nearvex[v] = -1;                sumweight += lowcost[v];                for(int j = 1; j <= n; j++)                {                    if(nearvex[j] != -1 && dis[v][j] < lowcost[j])                    {                        lowcost[j] = dis[v][j];                        nearvex[j] = v;                    }                }            }    }    out(sumweight);}long long in(char *s){    int len = strlen(s);    int id = len - 1;    for(int i = 0; i < len; i++)    {        if(s[i] == '.'){id = i; break;}    }    int cnt = len - 1 - id;    for(int i = 0; i < 2 - cnt; i++)        s[len++] = '0';    long long sum = 0;    for(int i = 0; i < len; i++)    {        if(s[i] == '.') continue;        int sx = s[i] - '0';        sum = sum * 10 + sx;    }    return sum;}int main(){    int T;    char s[26];    while(scanf("%d", &T) != EOF){    while(T--)    {        e = 0;        memset(head, -1, sizeof(head));        scanf("%d", &n);        for(int i = 1; i <= n; i++)            for(int j = 1; j <= n; j++)                {                    scanf("%s", s);                    dis[i][j] = in(s);                }        prim(1);        long long mi  = INF;        int pos = 1;        for(int i = 1; i <= n; i++)        {            spfa(i);            long long sum = 0;            for(int j = 1; j <= n; j++)            {                sum += d[j];            }            if(sum < mi)            {                mi = sum;                pos = i;            }        }        mi *= 2;        cout << pos << " ";        out(mi);        printf("\n");        //printf("%d %f\n\n", pos, mi * 2);    }    }    return 0;}