• ZOJ 3456 Traveler Nobita 最小生成树


    Traveler Nobita

    Time Limit: 2 Seconds      Memory Limit: 65536 KB

    One day, Nobita used a time machine and went back to 1000 AD. He found that there are N cities in the kingdom he lived. The cities are numbered from 0 toN - 1. Before 1000 AD., there are no roads between any two cities. The kingdom will build one road between two cities at the beginning of each year starting from 1000 AD. There might be duplicated roads between two cities being built by the kingdom. You can assume that building a road takes no time.

    At the beginning of every year, after the new road is built, Nobita will try to make a schedule to travel around all cities within that year. The travel should both begin at and end at the capital city - city0. Every time Nobita arrived at a city i, he will spent t1i days in that city, regardless of how many times he had come to the city. Of course he wouldn't need to spend any time in the capital city (that is to say, t10 is always 0). And t2i hours is required to pass road #i. Note that to pass each road, a passport of that road is required. And the kingdom limits that one person can only have no more than N - 1 passports of roads each year.

    You are given information about the roads built in M years. Please find out the minimum time Nobita needed to complete his traveling schedule.

    Input

    There are multiple cases. The first line of a test case contains two integers, N (2 ≤ N ≤ 200) and M (1 ≤ M ≤ 10000). The next line contains N integers, indicating t10 ... t1n - 1. (0 ≤ t1i ≤ 50) The next M lines, the ith (0 ≤ i < M) line of this section contains three integers, uivit2i, (0 ≤ uivi < N; 0 ≤ t2i ≤ 5000), indicating that in year 1000 + i AD., a road will be built between city ui and city vit1i and t2i have been described above.

    Output

    For each case, you should output M lines. For the ith line, if Nobita can make a schedule in year 1000 + i, output the minimal days he can finish that schedule, rounded to two decimal digits. Otherwise output -1. There should be a blank line after each case.

    Sample Input

    5 6
    0 5 2 5 4
    0 1 1
    0 2 2
    0 3 5
    3 4 2
    2 4 4
    1 2 1
    

    Sample Output

    -1
    -1
    -1
    21.83
    19.00
    19.00
    
    
    题意:有n个城市。每年修一条路,总共修m年。注意是从1000年開始的。Nobita想要每年走完一次n个城市,每次从0号出发,最后再回到0号,在每一个城市待t1天。从一个城市到还有一个城市要t2小时,注意这里的时间单位不统一。推断年份时,也要注意闰年和平年
    
    
    思路:kruscal就可以找到最短的路线。对于u,v两个点之间的边权,存的是在u,v两个城市呆的时间和行走路程所用时间。在0号不须要花费时间。

    kruscal过程中有一个优化。即假设两个点已经是一个集合中的,那么连接这两点的边就能够删除。由于之前已经有花费更少的边了,所以这条边。就是没用的。

    #include <iostream>
    #include <stdio.h>
    #include <string>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <set>
    #include <queue>
    #include <stack>
    #include <vector>
    #define N 10009
    using namespace std;
    
    int n,m;
    int num;
    int a[N];
    int fa[N];
    
    struct node
    {
      int u,v,len;
      bool operator<(const node &a)const
      {
          return len<a.len;
      }
    };
    vector<node>ed;
    
    int findfa(int x)
    {
        int r = x, t;
    
        while(r!=fa[r])
              r=fa[r];
    
       // for(;fa[r]>=0;r=fa[r]);
    
        while(x!=r)
        {
            t = fa[x];
            fa[x] = r;
            x = t;
        }
    
        return r;
    }
    
    int check(int x)
    {
        if(x%400==0 || (x%4==0&&x%100))
        return 1;
    
        return 0;
    }
    
    void add(int u,int v,int w)
    {
        node e={u,v,(a[u]+a[v])*24+w*2};
        ed.push_back(e);
    }
    
    void uniontwo(int a,int b)
    {
        int aa=findfa(a);
        int bb=findfa(b);
        int tmp=fa[aa]+fa[bb];
        if(fa[aa]>fa[bb])
        {
            fa[aa]=bb;
            fa[bb]=tmp;
        }
        else
        {
            fa[bb]=aa;
            fa[aa]=tmp;
        }
    }
    
    int kruscal()
    {
        for(int i=1;i<=n;i++)fa[i]=i;
    
        sort(ed.begin(),ed.end());
        int ans=0,cnt=0;
    
    //    for(vector<node>::iterator it=ed.begin();it!=ed.end();it++)
    //    {
    //        cout<<it->u<<" "<<it->v<<" "<<it->len<<endl;
    //    }
    
        for(vector<node>::iterator it=ed.begin();it<ed.end();)
        {
            int u=it->u;
            int v=it->v;
            int l=it->len;
            int fu=findfa(u);
            int fv=findfa(v);
    
            if( findfa(u)!=findfa(v) )
            {
                ans+=l;
                cnt++;
                it++;
                if(fv>fu)fa[fv]=fu;
                else
                fa[fu]=fv;
                //uniontwo(u,v);
            }
            else
            ed.erase(it);//已经有更小的边用于连接,此边即没什么用。可删除
        }
        //cout<<"cnt="<<cnt<<endl;
    
        if(cnt<n-1) return -1;
        return ans;
    
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            num=0;
            for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
    
            ed.clear();
            int u,v,w;
    
            for(int i=0;i<m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
    
                if(i<n-2)
                {
                    puts("-1");
                    continue;
                }
    
                int x=kruscal();
                //cout<<"********"<<endl;
    
                //cout<<"x="<<x<<endl;
                if(x==-1)
                {
                    puts("-1");
                    continue;
                }
                int yy;
                if(check(1000+i)) yy=366;
                else yy=365;
    
                if(yy*24<x)
                puts("-1");
                else
                printf("%.2f
    ",x/24.0);
    
            }
            puts("");
    
        }
    
        return 0;
    }
    
    
    
    


    
    





  • 相关阅读:
    UltraEdit程序设置添加到右键菜单
    UltraEdit加入到右键菜单中
    vim常用命令
    Linux vi命令大全
    vi/vim 计算搜寻关键字数量
    vi 删除全部内容
    vi中全选的命令或者快捷方式
    VI打开和编辑多个文件的命令
    vi/vim 查找替换使用方法
    VMware workstation 与 VMware GSX Server 的区别
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7358253.html
Copyright © 2020-2023  润新知