中国海洋大学第四届朗讯杯高级组 Super Phyllis

来源:互联网 发布:壁虎老师java视频教程 编辑:程序博客网 时间:2024/04/29 21:55

Super Phyllis

Time Limit: 1000MS    Memory limit: 65536K

题目描述

Phyllis works for a large, multi-national corporation. She moves from department to department where her job is to uncover and remove any redundancies inherent in the day-to-day activities of the workers. And she is quite good at her job.

During her most recent assignment, she was given the following chart displaying the chain of commandwithin the department:
                       

Whenever anyone needs to send a report to their bosses, they use the above chart, sending one report along each arrow. Phyllis realized almost instantly that there were redundancies here. Specifically, since D sends a report to B and B sends a report to A, there\'s really no need for D to send a report to A directly, since it will be summarized in the report B sends to A. Thus the connection from D to A can be removed. If there had also been a connection from C to B, then the connections from D to B and C to A could have been removed as well.

Phyllis would like your help with this. Given a description of a chart like the one above, she would like a program that identifies all connections that can be removed from the chart.

输入

The first line of each test case will contain a positive integer m indicating the number of connections in the chart. Following that will be m lines each containing two strings s1 s2 indicating that there is a connection from employee s1 to his/her boss s2. In any test case there will be no more than 200 employees listed and no connection will appear more than once. A line containing a single 0 will terminate the input.

输出

For each test case, output the number of connections that should be removed followed by a list of the deleted connections in lexicographic order. Connection s1 s2 should be represented by the string s1,s2.

示例输入

5D BD CD AB AC A6D BD CD AC BB AC A1Danny Tessa0

示例输出

Case 1: 1 D,ACase 2: 3 C,A D,A D,BCase 3: 0

提示

来源

中国海洋大学第四届朗讯杯高级组

 

 

因为数组开小一直疯狂的RE,我还一直以为是queue出了问题,在SDUT的的OJ上丧心病狂的提交了20多遍最后换成vector才过掉。

首先这个题是不存在环的。

对每个点进行bfs。开始的点层数设为1,依层拓展,如果除了第一层之外的某层拓展到第二层的点,也就是说某个点连接着第二层的点,则说明从出发点(第一层的点)到这个第二层的点之间的边可以删掉。对所有点bfs就可以得到所有多余的边。

 

 

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <string>#include <map>#define MAXN 205using namespace std;map<string,int> mp1;map<int,string> mp2;bool gl[MAXN][MAXN];int n,cnt;int d[MAXN];string ans[20000];void bfs(int v){    memset(d,0,sizeof(d));    queue<int> que;    que.push(v);    d[v]=1;    while(!que.empty())    {        int tmp=que.front();        que.pop();        for(int i=1; i<=n; ++i)            if(gl[tmp][i])            {                if(!d[i])                {                    d[i]=d[tmp]+1;                    que.push(i);                }                else                {                    if(d[i]==2&&gl[v][i])                    {                        string str=mp2[v]+","+mp2[i];                        ans[cnt].clear();                        ans[cnt++]=str;                        gl[v][i]=false;                    }                }            }    }}int main(){    int m,kase=0;    while(cin>>m&&m)    {        string a,b;        memset(gl,0,sizeof(gl));        mp1.clear();        mp2.clear();        n=0;        for(int i=0; i<m; ++i)        {            cin>>a>>b;            if(!mp1[a])            {                ++n;                mp1[a]=n;                mp2[n]=a;            }            if(!mp1[b])            {                ++n;                mp1[b]=n;                mp2[n]=b;            }            gl[mp1[a]][mp1[b]]=true;        }        cnt=0;        for(int i=1; i<=n; ++i)            bfs(i);        sort(ans,ans+cnt);        cout<<"Case "<<++kase<<": "<<cnt;        for(int i=0; i<cnt; ++i)            cout<<" "<<ans[i];        cout<<endl;    }    return 0;}


 

原创粉丝点击