zoukankan      html  css  js  c++  java
  • CSUFT2016训练赛

    解题报告:

    Fence Repair

    Time Limit: 2000MS

     

    Memory Limit: 65536K

    Total Submissions: 39958

     

    Accepted: 13033

    Description

    Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000) planks of wood, each having some integer length Li (1 ≤ Li ≤ 50,000) units. He then purchases a single long board just long enough to saw into the N planks (i.e., whose length is the sum of the lengths Li). FJ is ignoring the "kerf", the extra length lost to sawdust when a sawcut is made; you should ignore it, too.

    FJ sadly realizes that he doesn't own a saw with which to cut the wood, so he mosies over to Farmer Don's Farm with this long board and politely asks if he may borrow a saw.

    Farmer Don, a closet capitalist, doesn't lend FJ a saw but instead offers to charge Farmer John for each of the N-1 cuts in the plank. The charge to cut a piece of wood is exactly equal to its length. Cutting a plank of length 21 costs 21 cents.

    Farmer Don then lets Farmer John decide the order and locations to cut the plank. Help Farmer John determine the minimum amount of money he can spend to create the N planks. FJ knows that he can cut the board in various different orders which will result in different charges since the resulting intermediate planks are of different lengths.

    Input

    Line 1: One integer N, the number of planks 
    Lines 2..N+1: Each line contains a single integer describing the length of a needed plank

    Output

    Line 1: One integer: the minimum amount of money he must spend to make N-1 cuts

    Sample Input

    3

    8

    5

    8

    Sample Output

    34

    Hint

    He wants to cut a board of length 21 into pieces of lengths 8, 5, and 8. 
    The original board measures 8+5+8=21. The first cut will cost 21, and should be used to cut the board into pieces measuring 13 and 8. The second cut will cost 13, and should be used to cut the 13 into 8 and 5. This would cost 21+13=34. If the 21 was cut into 16 and 5 instead, the second cut would cost 16 for a total of 37 (which is more than 34).

    Source

    USACO 2006 November Gold

    题意:

    要8,5,8长的木板,最少要截多少钱,首先是21米的,要截21元,截成了8,13,再截13,要13元截成了5,8,求最少要多少钱。

    分析:

    刚一开始,感觉是贪心,每次截出最大的,这样就变成了不断求部分和,然而,数据量还算比较大,又想到线段树。WA了好几次,才想到是方案不对。

    哈夫曼编码,首先选出最小的两个,截他们的费用最少,但是在此之前,这两节又是原先的木板中截出来的,这样就想到了是一个哈夫曼编码的原理。

    #include <stdio.h>
    #include <queue>
    
    using namespace std;
    
    int main()
    {
        int n;
        scanf("%d",&n);
    
        priority_queue<int,vector<int>,greater<int> > Q;
    
        int tmp;
        for(int i=0;i<n;i++)
        {
            scanf("%d",&tmp);
            Q.push(tmp);
        }
        long long sum =0;
        while(Q.size()>1)
        {
            int a = Q.top();
            Q.pop();
            int b = Q.top();
            Q.pop();
            sum+=(a+b);
            Q.push(a+b);
        }
    
        printf("%lld
    ",sum);
    
        return 0;
    }
    View Code
     

    Invitation Cards

    Time Limit: 8000MS

     

    Memory Limit: 262144K

    Total Submissions: 25091

     

    Accepted: 8293

    Description

    In the age of television, not many people attend theater performances. Antique Comedians of Malidinesia are aware of this fact. They want to propagate theater and, most of all, Antique Comedies. They have printed invitation cards with all the necessary information and with the programme. A lot of students were hired to distribute these invitations among the people. Each student volunteer has assigned exactly one bus stop and he or she stays there the whole day and gives invitation to people travelling by bus. A special course was taken where students learned how to influence people and what is the difference between influencing and robbery. 

    The transport system is very special: all lines are unidirectional and connect exactly two stops. Buses leave the originating stop with passangers each half an hour. After reaching the destination stop they return empty to the originating stop, where they wait until the next full half an hour, e.g. X:00 or X:30, where 'X' denotes the hour. The fee for transport between two stops is given by special tables and is payable on the spot. The lines are planned in such a way, that each round trip (i.e. a journey starting and finishing at the same stop) passes through a Central Checkpoint Stop (CCS) where each passenger has to pass a thorough check including body scan. 

    All the ACM student members leave the CCS each morning. Each volunteer is to move to one predetermined stop to invite passengers. There are as many volunteers as stops. At the end of the day, all students travel back to CCS. You are to write a computer program that helps ACM to minimize the amount of money to pay every day for the transport of their employees. 

    Input

    The input consists of N cases. The first line of the input contains only positive integer N. Then follow the cases. Each case begins with a line containing exactly two integers P and Q, 1 <= P,Q <= 1000000. P is the number of stops including CCS and Q the number of bus lines. Then there are Q lines, each describing one bus line. Each of the lines contains exactly three numbers - the originating stop, the destination stop and the price. The CCS is designated by number 1. Prices are positive integers the sum of which is smaller than 1000000000. You can also assume it is always possible to get from any stop to any other stop.

    Output

    For each case, print one line containing the minimum amount of money to be paid each day by ACM for the travel costs of its volunteers.

    Sample Input

    2

    2 2

    1 2 13

    2 1 33

    4 6

    1 2 10

    2 1 60

    1 3 20

    3 4 10

    2 4 5

    4 1 50

    Sample Output

    46

    210

    Source

    Central Europe 1998

    之前做过,所以SPFA写的比较详细。

    题意:给出n个点和n条有向边,求所有点到源点1的来回最短路之和(保证每个点都可以往返源点1).

    思路:建反图,从任意一点回来,就变成了反图上的从1到任意一点去。

    next记录前驱,head[u],记录u是在第几条边,然后往前扫。例如:edge[0].next = head[1] =0;head[1] = 0;edge[3].next = head[1] =0;head[1] =3;

    再扫的时候就是,3->0;

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<vector>
    #include<queue>
    using namespace std;
    #define MAXN 1000100
    #define inf 0x3f3f3f3f
    
    struct Edge
    {
        int v,w,next;
    } edge1[MAXN*10],edge2[MAXN*10];
    
    int cnt[MAXN];
    int head1[MAXN],head2[MAXN];
    long long dist[MAXN];
    bool mark[MAXN];
    int n,m,NE;
    
    void add(Edge *edge,int *head,int u,int v,int w)
    {
        edge[NE].v=v;
        edge[NE].w=w;
        edge[NE].next=head[u];  //边的前驱是head[u],之前的那条边
        head[u]=NE;     //head[u] 重新覆盖
    }
    
    
    long long SPFA(Edge *edge,int *head,int u)
    {
        memset(mark,false,sizeof(mark));
        memset(cnt,0,sizeof(cnt));
        
        for(int i=1; i<=n; i++)
            dist[i]=inf;
        dist[u]=0;
        mark[u] =true;
        queue<int>Q;
        Q.push(u);
        while(!Q.empty())
        {
            u=Q.front();
            Q.pop();
            mark[u]=false;
            for(int i=head[u]; i!=-1; i=edge[i].next)
            {
                int v=edge[i].v,w=edge[i].w;
                if(dist[u]+w<dist[v])
                {
                    dist[v]=dist[u]+w;
                    if(!mark[v])
                    {
                        mark[v]=true;
                        Q.push(v);
                        
                        /*if(++cnt[v]>n)
                            return false;*/
                    }
                }
            }
        }
        long long ans=0;
        for(int i=2; i<=n; i++)ans+=dist[i];
        return ans;
    }
    
    int main()
    {
        int _case,u,v,w;
        scanf("%d",&_case);
        while(_case--)
        {
            scanf("%d%d",&n,&m);
            NE=0;
            memset(head1,-1,(n+2)*sizeof(int));
            memset(head2,-1,(n+2)*sizeof(int));
            while(m--)
            {
                scanf("%d%d%d",&u,&v,&w);
                add(edge1,head1,u,v,w);
                add(edge2,head2,v,u,w);//建反图
                NE++;
            }
            printf("%lld
    ",SPFA(edge1,head1,1)+SPFA(edge2,head2,1));
        }
        return 0;
    }
    View Code

    Sorting It All Out

    Time Limit: 1000MS

     

    Memory Limit: 10000K

    Total Submissions: 32928

     

    Accepted: 11444

    Description

    An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D implies that A < B, B < C and C < D. in this problem, we will give you a set of relations of the form A < B and ask you to determine whether a sorted order has been specified or not.

    Input

    Input consists of multiple problem instances. Each instance starts with a line containing two positive integers n and m. the first value indicated the number of objects to sort, where 2 <= n <= 26. The objects to be sorted will be the first n characters of the uppercase alphabet. The second value m indicates the number of relations of the form A < B which will be given in this problem instance. Next will be m lines, each containing one such relation consisting of three characters: an uppercase letter, the character "<" and a second uppercase letter. No letter will be outside the range of the first n letters of the alphabet. Values of n = m = 0 indicate end of input.

    Output

    For each problem instance, output consists of one line. This line should be one of the following three: 

    Sorted sequence determined after xxx relations: yyy...y. 
    Sorted sequence cannot be determined. 
    Inconsistency found after xxx relations. 

    where xxx is the number of relations processed at the time either a sorted sequence is determined or an inconsistency is found, whichever comes first, and yyy...y is the sorted, ascending sequence. 

    Sample Input

    4 6

    A<B

    A<C

    B<C

    C<D

    B<D

    A<B

    3 2

    A<B

    B<A

    26 1

    A<Z

    0 0

    Sample Output

    Sorted sequence determined after 4 relations: ABCD.

    Inconsistency found after 2 relations.

    Sorted sequence cannot be determined.

    Source

    East Central North America 2001

     

    题意:

    对于N个大写字母,给定它们的一些偏序关系,要求判断出经过多少个偏序关系之后可以确定它们的排序或者存在冲突,或者所有的偏序关系用上之后依旧无法确定唯一的排序。

    分析:

    每加一条边,就进行判断,是不是成环,或者已经可以排好。我这里WA的地方是,m的值,应该是每次删掉一个点后都要判断一下是不是有环或能否确定,也就是说查入度为0的循环放到for循环里面。

    #include <stdio.h>
    #include <string.h>
    
    bool maps[30][30];
    int degree[30];
    char ans[30];
    int n,m;
    
    int topu ()
    {
        int flag2=2;
        int in[30];
        for(int i=1; i<=n; i++)
            in[i] = degree[i];
    
        int pos = 1;
        int i,j;
        int tmp = 0;
        for(i=1; i<=n; i++)
        {
            int m =0;
            for(j=1; j<=n; j++)
            {
                if(in[j]==0)
                {
                    m++;
                    tmp = j;
                }
            }
            if(m==0)        ///有环
                return 0;
            if(m>1)
                flag2=1;
    
            ans[pos++] = tmp+'A'-1;
            in[tmp] --;
            for(int k=1; k<=n; k++)
            {
                if(maps[tmp][k]==true)
                    in[k]--;
            }
        }
        return flag2;
    }
    
    int main()
    {
        //freopen("input.txt","r",stdin);
        while(scanf("%d%d",&n,&m),n)
        {
            memset(degree,0,sizeof(degree));
            memset(maps,false,sizeof(maps));
    
            int anss = 0;
            int flag = -1;
            char str[10];
            for(int i=1; i<=m; i++)
            {
                scanf("%s",str);
                if(anss)
                    continue;
                int a = str[0] - 'A'+1;
                int b = str[2] - 'A'+1;
    
                maps[a][b] = true;
                degree[b] ++;
    
                flag=topu();
                if(flag==0)
                {
                    anss=1;
                    printf("Inconsistency found after %d relations.
    ",i);
                }
                if(flag==2)
                {
                    anss=1;
                    printf("Sorted sequence determined after %d relations: ",i);
                    for(int i=1; i<n; i++)
                        printf("%c",ans[i]);
                    printf("%c.
    ",ans[n]);
                }
            }
            if(flag==1)
                printf("Sorted sequence cannot be determined.
    ");
        }
        return 0;
    }
    View Code

    FDNY to the Rescue!

    Time Limit: 1000MS

     

    Memory Limit: 10000K

    Total Submissions: 2917

     

    Accepted: 896

    Description

    The Fire Department of New York (FDNY) has always been proud of their response time to fires in New York City, but they want to make their response time even better. To help them with their response time, they want to make sure that the dispatchers know the closest firehouse to any address in the city. You have been hired to write this software and are entrusted with maintaining the proud tradition of FDNY. Conceptually, the software will be given the address of the fire, the locations of the firehouses, street intersections, and the time it takes to cover the distance between each intersection. It will then use this information to calculate how long it takes to reach an address from each firehouse. 

    Given a specific fire location in the city, the software will calculate the time taken from all the fire stations located in the city to reach the fire location. The list of fire stations will be sorted from shortest time to longest time. The dispatcher can then pick the closest firestation with available firefighters and equipment to dispatch to the fire.

    Input

    Line 1: 
    # of intersections in the city, a single integer (henceforth referred to as N) N<20 

    Lines 2 to N+1: 
    A table (square matrix of integer values separated by one or more spaces) representing the time taken in minutes between every pair of intersections in the city. In the sample input shown below the value "3" on the 1st row and the 2nd column represents the time taken from intersection #1 to reach intersection #2. 

    Similarly the value "9" on the 4th row and the 2nd column represents the time taken from intersection #4 to reach intersection #2. 

    A value of -1 for time means that it is not possible to go directly from the origin intersection (row #) to the destination intersection (column #). All other values in the table are non-negative. 

    Line N+2: 
    An integer value n (<= N) indicating the intersection closest to the fire location followed by one or more integer values for the intersections closest to the fire stations (all on one line, separated by one or more spaces) will follow the input matrix. 

    Notes on input format: 

    1. The rows and columns are numbered from 1 to N. 
    2. All input values are integers 
    3. All fire locations are guaranteed reachable from all firehouses. 
    4. All distance calculations are made from the intersection closest to each firehouse to the intersection closest to the fire. 

    Output

    Line 1: 
    A label line with the headings for each column, exactly as shown in the example. 

    Line 2 onwards (one line for each fire station): 
    A sorted list (based on time) showing the fire station (origin), the destination site, time taken and a complete shortest path of nodes from the originating fire station to the fire location. 

    Notes on output format: 
    1. Columns are tab separated. 
    2. If two or more firehouses are tied in time they can be printed in any order. 
    3. If more than one path exists that has the same minimal time for a given location & firehouse, either one can be printed on the output. 
    4. If the fire location and the fire station locations happen to be the same intersection, the output will indicate that the origin and destination have the same intersection number, the time will be "0" and the nodes in the shortest path will show just one number, the fire location. 
    Next is the picture for the sample input data. 

     

    Sample Input

    6

    0  3  4 -1 -1 -1

    -1 0  4  5 -1 -1

    2  3  0 -1 -1  2

    8  9  5  0  1 -1

    7  2  1 -1  0 -1

    5 -1  4  5  4  0

    2  4  5  6

    In the above input the last line indicates that "2" is the location of the fire and "4", "5" and "6" are the intersections where fire stations are located.

    Sample Output

    Org   Dest  Time  Path

    5     2     2     5     2

    4     2     3     4     5     2

    6     2     6     6     5     2

    Source

    Mid-Atlantic 2001

    题意:

    6个节点,下面是6行6列,表示i到j的距离。2是终点,4,5,6,是消防车的起点,求这些消防车到终点的最短时间,时间从小到大排好。

    分析:

    可以建反图,就成了从起火的地方开始的单源点的最短路了。

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    
    using namespace std;
    
    #define INF 0x3f3f3f3f
    
    int start,send;
    int maps[30][30];
    int dis[30];
    int pre[30];
    bool vis[30];
    int n;
    struct Node {
        int time;
        int org;
        int dest;
    }ans[50];
    
    bool cmp(Node a,Node b)
    {
        return a.time<b.time;
    }
    
    void Dijkstra(int s)
    {
        memset(pre,0,sizeof(pre));
        memset(vis,false,sizeof(vis));
    
    
        for(int i=1; i<=n; i++)
        {
            dis[i] = maps[s][i];
            pre[i] = s;
        }
        pre[s] = -1;
        dis[s] = 0;
        vis[s] = true;
    
        for(int i=1; i<n; i++)
        {
            int k = 0,tmp = INF;
            for(int j=1; j<=n; j++)
            {
                if(vis[j]) continue;
                if(dis[j]<tmp)
                {
                    tmp = dis[j];
                    k = j;
                }
            }
            vis[k] = true;
    
            for(int j=1; j<=n; j++)
            {
                if(vis[j]) continue;
                if(dis[j]>dis[k]+maps[k][j])
                {
                    dis[j] = dis[k] + maps[k][j];
                    pre[j] = k;
                }
            }
        }
    }
    
    ///org
    void print(int x)
    {
        if(pre[x]!=-1)
        {
            printf("%d    ",x);
            print(pre[x]);
        }
    }
    
    int main()
    {
        scanf("%d",&n);
    
        for(int i=1; i<=n; i++)
            for(int j=1; j<=n; j++)
            {
                scanf("%d",&maps[j][i]);
                if(maps[j][i]==-1)
                    maps[j][i] = INF;
            }
        scanf("%d",&send);
        Dijkstra(send);
    
        int t=0;
        while(scanf("%d",&start)!=EOF)
        {
            ans[t].time = dis[start];
            ans[t].dest = send;
            ans[t++].org = start;
        }
    
        sort(ans,ans+t,cmp);
    
        printf("Org    Dest    Time    Path
    ");
        for(int i=0;i<t;i++)
        {
            printf("%d    %d    %d    ",ans[i].org,ans[i].dest,ans[i].time);
            print(ans[i].org);
            printf("%d
    ",ans[i].dest);
        }
    
        return 0;
    }
    View Code

    Currency Exchange

    Time Limit: 1000MS

     

    Memory Limit: 30000K

    Total Submissions: 26669

     

    Accepted: 9857

    Description

    Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be several points specializing in the same pair of currencies. Each point has its own exchange rates, exchange rate of A to B is the quantity of B you get for 1A. Also each exchange point has some commission, the sum you have to pay for your exchange operation. Commission is always collected in source currency. 
    For example, if you want to exchange 100 US Dollars into Russian Rubles at the exchange point, where the exchange rate is 29.75, and the commission is 0.39 you will get (100 - 0.39) * 29.75 = 2963.3975RUR. 
    You surely know that there are N different currencies you can deal with in our city. Let us assign unique integer number from 1 to N to each currency. Then each exchange point can be described with 6 numbers: integer A and B - numbers of currencies it exchanges, and real RAB, CAB, RBA and CBA - exchange rates and commissions when exchanging A to B and B to A respectively. 
    Nick has some money in currency S and wonders if he can somehow, after some exchange operations, increase his capital. Of course, he wants to have his money in currency S in the end. Help him to answer this difficult question. Nick must always have non-negative sum of money while making his operations. 

    Input

    The first line of the input contains four numbers: N - the number of currencies, M - the number of exchange points, S - the number of currency Nick has and V - the quantity of currency units he has. The following M lines contain 6 numbers each - the description of the corresponding exchange point - in specified above order. Numbers are separated by one or more spaces. 1<=S<=N<=100, 1<=M<=100, V is real number, 0<=V<=103
    For each point exchange rates and commissions are real, given with at most two digits after the decimal point, 10-2<=rate<=102, 0<=commission<=102
    Let us call some sequence of the exchange operations simple if no exchange point is used more than once in this sequence. You may assume that ratio of the numeric values of the sums at the end and at the beginning of any simple sequence of the exchange operations will be less than 104

    Output

    If Nick can increase his wealth, output YES, in other case output NO to the output file.

    Sample Input

    3 2 1 20.0

    1 2 1.00 1.00 1.00 1.00

    2 3 1.10 1.00 1.10 1.00

    Sample Output

    YES

    Source

    Northeastern Europe 2001, Northern Subregion

    题意:

    3种货币,2种兑换方式,拥有第1种货币20.0元,

    1-2这两种货币之间的兑换1->2汇率为1.00,手续费1.00元,2->1汇率1.00,手续费1.00

    是否可以赚钱。

    分析:

    SPFA判正环,注意松弛条件,dist[v] = min(dist[u],(dist[u]-edge[i].c)*egde[i].r);

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    #include <algorithm>
    
    using namespace std;
    #define N 210
    #define INF 0xfffffff
    double dist[N], money;
    int NE, head[N], cnt[N], vis[N];
    int n, m, s;
    
    struct Edge
    {
        int v, next;
        double r, c;
    }edge[N];
    
    void add(int u, int v, double r, double c)
    {
        edge[NE].v = v;
        edge[NE].r = r;
        edge[NE].c = c;
        edge[NE].next = head[u];
        head[u] = NE++;
    }
    
    bool spfa()
    {
        memset(vis, 0, sizeof(vis));
        memset(cnt, 0, sizeof(cnt));
    
        vis[s] = true;
        dist[s] = money;
        queue<int>Q;
        Q.push(s);
        cnt[s]++;
    
        while(Q.size())
        {
            int u=Q.front();
            Q.pop();
            vis[u] = false;
            for(int i=head[u]; i!=-1; i=edge[i].next)
            {
                int v = edge[i].v;
                if(dist[v] < (dist[u] - edge[i].c) * edge[i].r)
                {
                    dist[v] = (dist[u] - edge[i].c) * edge[i].r;
                    if(!vis[v])
                    {
                        vis[v] = true;
                        Q.push(v);
                        cnt[v] ++;
                        if(cnt[v]>n)
                            return true;
                    }
                }
            }
    
        }
        if(dist[s]>money)
            return true;
        return false;
    }
    
    int main()
    {
        int u, v;
        double ruv, rvu, cuv, cvu;
        while(scanf("%d%d%d%lf", &n, &m, &s, &money)!=EOF)
        {
            NE = 0;
            memset(head, -1, sizeof(head));
            memset(dist, 0, sizeof(dist));
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d%lf%lf%lf%lf", &u, &v, &ruv, &cuv, &rvu, &cvu);
                add(u, v, ruv, cuv);
                add(v, u, rvu, cvu);
            }
            if( spfa() )
                printf("YES
    ");
            else
                printf("NO
    ");
        }
        return 0;
    }
    View Code

    Borg Maze

    Time Limit: 1000MS

     

    Memory Limit: 65536K

    Total Submissions: 12912

     

    Accepted: 4209

    Description

    The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. The Borg collective is the term used to describe the group consciousness of the Borg civilization. Each Borg individual is linked to the collective by a sophisticated subspace network that insures each member is given constant supervision and guidance. 

    Your task is to help the Borg (yes, really) by developing a program which helps the Borg to estimate the minimal cost of scanning a maze for the assimilation of aliens hiding in the maze, by moving in north, west, east, and south steps. The tricky thing is that the beginning of the search is conducted by a large group of over 100 individuals. Whenever an alien is assimilated, or at the beginning of the search, the group may split in two or more groups (but their consciousness is still collective.). The cost of searching a maze is definied as the total distance covered by all the groups involved in the search together. That is, if the original group walks five steps, then splits into two groups each walking three steps, the total distance is 11=5+3+3.

    Input

    On the first line of input there is one integer, N <= 50, giving the number of test cases in the input. Each test case starts with a line containg two integers x, y such that 1 <= x,y <= 50. After this, y lines follow, each which x characters. For each character, a space `` '' stands for an open space, a hash mark ``#'' stands for an obstructing wall, the capital letter ``A'' stand for an alien, and the capital letter ``S'' stands for the start of the search. The perimeter of the maze is always closed, i.e., there is no way to get out from the coordinate of the ``S''. At most 100 aliens are present in the maze, and everyone is reachable.

    Output

    For every test case, output one line containing the minimal cost of a succesful search of the maze leaving no aliens alive.

    Sample Input

    2

    6 5

    #####

    #A#A##

    # # A#

    #S  ##

    #####

    7 7

    ##### 

    #AAA###

    #    A#

    # S ###

    #     #

    #AAA###

    ##### 

    Sample Output

    8

    11

    Source

    Svenskt Mästerskap i Programmering/Norgesmesterskapet 2001

    题意:求S到所有A的最小生成树。

    分析:BFS求出每个S和A的所有点之间的最短路,然后建图,求最小生成树。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    
    using namespace std;
    
    #define maxe 100000
    #define N 1005
    
    int a[N][N];
    int father[N];
    
    struct Edge
    {
        int a,b;
        int len;
    } edge[maxe];
    
    
    struct stud1
    {
        int x,y;
        int time;
    };
    
    int step[4][2]= {{1,0},{-1,0},{0,1},{0,-1}};
    
    int n,m;
    int vis[N][N];
    int k;
    
    int judge(int x,int y)
    {
        if(x>=0&&x<n&&y>=0&&y<m)
            return 1;
        return 0;
    }
    
    int Find_Set(int x)
    {
        if(x!=father[x])
            father[x]=Find_Set(father[x]);
        return father[x];
    }
    
    bool cmp(Edge a,Edge b)
    {
        return a.len<b.len;
    }
    
    void bfs(int x,int y)
    {
        queue<stud1>q;
    
        while(!q.empty())
            q.pop();
    
        stud1 cur,next;
        cur.x=x;
        cur.y=y;
        cur.time=0;
    
        q.push(cur);
    
        memset(vis,0,sizeof(vis));
    
        vis[x][y]=1;
    
        while(!q.empty())
        {
            cur=q.front();
            q.pop();
            for(int i=0; i<4; i++)
            {
                int xx=cur.x+step[i][0];
                int yy=cur.y+step[i][1];
                if(!judge(xx,yy)||a[xx][yy]<0||vis[xx][yy])
                    continue;
    
                next.x=xx;
                next.y=yy;
                next.time=cur.time+1;
    
                vis[xx][yy]=1;
    
                if(a[xx][yy]>=1)
                {
                    edge[k].a=a[x][y];
                    edge[k].b=a[xx][yy];
                    edge[k++].len=next.time;
                }
                q.push(next);
            }
        }
    }
    
    int main()
    {
        int t,i,j;
        scanf("%d",&t);
    
        while(t--)
        {
            scanf("%d%d",&m,&n);
            char s[1000];
            gets(s); 
            int num=0;
            k=0;
    
            char c;
    
            for(i=0; i<n; i++)
            {
                for(j=0; j<m; j++)
                {
                    scanf("%c",&c);
    
                    if(c=='#')
                        a[i][j]=-1;
                    else if(c==' ')
                        a[i][j]=0;
                    else
                        a[i][j]=++num; //出现的S或A依次递增赋值
    
                }
                getchar();
            }
    
            for(i=0; i<n; i++)
                for(j=0; j<m; j++)
                    if(a[i][j]>0)
                        bfs(i,j);
    
            for(i=0; i<=num; i++)
                father[i]=i;
    
            sort(edge,edge+k,cmp);
            int ans=0;
            for(i=0; i<k; i++)
            {
                int aa=Find_Set(edge[i].a);
                int bb=Find_Set(edge[i].b);
                if(aa!=bb)
                {
                    ans+=edge[i].len;
                    father[aa]=bb;
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code

  • 相关阅读:
    Python List+Tuple+Dict+Set小结
    小命要紧~风热风寒感冒
    IDEA忽略编译报错
    IDEA新建一个Spring Boot项目
    ip2region.jar实现ip转地址
    IDEA控制台中文乱码问题
    IDEA报错Plugin "XXX" was not loaded: required plugin "Java EE: EJB, JPA, Servlets" is disabled.
    IDEA Error:java: Compilation failed: internal java compiler error
    Failed to start component [StandardEngine[Catalina].StandardHost[localhost]
    浏览网页隐藏服务器IP
  • 原文地址:https://www.cnblogs.com/TreeDream/p/5745761.html
Copyright © 2011-2022 走看看