If you've seen television commercials for long-distance phone companies lately, you ' ve noticed Thatmany companies has bee N spending a lot of money trying to convince people, they provide thebest service at the lowest cost. One company has "calling circles." You provide a list of people thatyou the most frequently. If you call someone in your calling circle (who's also a customer of the Samecompany), you get bigger discounts than if Y ou call outside your circle. Another company points outthat your only get the big discounts for people in your calling circle, and if your change Callmost frequently, it's up to the add them to your calling circle. Libertybell Phone Co. is a new company, that thinks they has the calling plan that can put othercompanies out of business. Libertybell had calling circles, but they figure out your calling Circle Foryou. How it works. Libertybell keeps track of all phone calls. In addition to yourself, yourcalling Circle consists of all PEOPle whom you and the WHO call you, either directly or indirectly. For example, if Ben calls Alexander, Alexander calls Dolly, and Dolly calls Ben, they is all withinthe same circle. If Dolly also calls Benedict and Benedict calls Dolly, then Benedict are in the samecalling circle as Dolly, Ben, and Alexa NDEr. Finally, if Alexander calls Aaron but Aaron doesn ' t callalexander, Ben, Dolly, or Benedict, then Aaron was not in the CIRCL E.you ' ve been hired by Libertybell to write the program to determine calling circles given a log ofphone calls between PEO Ple. Inputthe input file would contain one or more data sets. Each data set begins with a line containing Twointegers, N and M. The first integer, n, represents the number of different people who is in the dataset. The maximum value for n is 25. The remainder of the data set consists of M lines, each Representinga phone call. Each call was represented by and names, separated by a single space. Names is first namesonly (unique within a data seT), is case sensitive, and consist of the only alphabetic characters; No Nameis longer than letters. For example, if Ben called Dolly, it would are represented in the data file Asben Dollyinput are terminated by values of Zer O (0) for N and m.outputfor all input set, print a header line with the data set number, followed by Ingcircle in that data set. Each calling Circle line contains the names of all the people in an order withinthe circle, separated by Comma-space (a C Omma followed by a space). Output sets is separated byblank lines. Sample Input5 6Ben alexanderalexander dollydolly bendolly benedictbenedict dollyalexander Aaron14 34John Aaronaaron Bened Ictbetsy johnbetsy Ringoringo dollybenedict pauljohn betsyjohn aaronbenedict georgedolly RingoPaul MarthaGeorge Benalexander georgebetsy ringoalexander stephenmartha stephenbenedict alexanderstephen PaulBetsy RingoQuincy MarthaBen Patrickbetsy ringopatrick stephenpaul alexanderpatrick benstephen Quincyringo betsybetsY benedictbetsy benedictbetsy benedictbetsy benedictbetsy benedictbetsy benedictquincy Martha0 0Sample OutputCalling Circles for data set 1:ben, Alexander, Dolly, benedictaaroncalling circles for data set 2:john, Betsy, Ringo, Dollyaaronbe Nedictpaul, George, Martha, Ben, Alexander, Stephen, Quincy, Patrick
Test instructions
There are n individuals, M-time one-way calls. A telephone circle means that the person in the circle can be contacted directly or indirectly by 22. Find out all the phone rings
Analysis
Method 1:tarjan algorithm. Directly sets the template, separates each strong connected component can.
Method 2: Rujia analysis, the Floyd algorithm is used to find the transitive closure of the graph (can Baidu). Then through the closure, we know whether any i,j belong to the same strong Unicom component, and check the set maintenance.
"Code--transitive closure + and check set"
#include <bits/stdc++.h> using namespace std;
vector<string>v;
map<string,int>m;
int fa[200];
int ffind (int x) {return fa[x]==x?x:fa[x]=ffind (Fa[x]),} bool Join (int x,int y) {x=ffind (x); Y=ffind (y); if (x!=y) fa[x]=y;}
int main () {int map[30][30],n,m,t=0;
while (cin>>n>>m,m) {memset (map,0,sizeof (MAP));
for (int i=1;i<=n;i++) fa[i]=i;
V.clear ();
M.clear ();
while (m--) {string A, B;
cin>>a>>b; if (!
M.count (a)) {v.push_back (a);
M[a]=v.size (); } if (!
M.count (b)) {v.push_back (b);
M[b]=v.size ();
} map[m[a]][m[b]]=1;
} for (int k=1;k<=n;k++) for (int i=1;i<=n;i++) for (int j=1;j<=n;j++)//transitive closure {
map[i][j]|=map[i][k]&map[k][j]; } for (int i=1;i<=n;i++) for (int j=1;j<i;j++) if (Map[i][j]&map[j][i]) join (I,J);
if (t++) printf ("\ n");
printf ("Calling circles for data set%d:\n", t);
for (int i=1;i<=n;i++) if (fa[i]==i) {cout<<v[i-1];
for (int j=1;j<=n;j++) if (I!=j&&ffind (j) ==i) cout<< "," <<V[j-1];
cout<<endl; }
}
}
Code--tarjan
#include <bits/stdc++.h> using namespace std;
const int max=202020; struct node{int s,t,next;}
E[max];
int head[max],cnt;
void Add (int u,int v) {E[cnt]=node{u,v,head[u]};
head[u]=cnt++;
} int dfn[max];//The access time number of each node int low[max];//the smallest number int sta[max],top each point can reach;
int scc[max];//the component ordinal int In[max],out[max] that each point belongs to; void Tardfs (int u,int &lay,int &sig) {low[u]=dfn[u]=lay++;//time to arrive at this point sta[top++]=u;//push in stack for (int i=head
[u];~i;i=e[i].next) {int t=e[i].t;
if (dfn[t]==0) {Tardfs (T,LAY,SIG);
Low[u]=min (Low[u],low[t]); } else if (!
SCC[T])//Visited Low[u]=min (Low[u],dfn[t]);//strong connectivity method can use low} if (Low[u]==dfn[u])//u can not reach any previously traversed point {
sig++;
while (1) {int j=sta[--top];//out stack scc[j]=sig;
if (j==u) break;
}//contains U's connected component out of stack}} int Tarjan (int n) {int sig=0;//strong connected number int lay=1;//time stamp top=0; memset (scc,0,sizeof (SCC));
memset (dfn,0,sizeof (DFN));//timestamp 0 for (int i=1;i<=n;i++) {if (!dfn[i]) Tardfs (I,LAY,SIG);
} return sig;//returns the number of connected} int n,m;
vector<string>v,ans[27];
map<string,int>m;
BOOL CMP (VECTOR<STRING>A,VECTOR<STRING>B) {return a[0]<b[0];} int main () {int t=0;
while (Cin>>n>>m,n) {for (int i=0;i<=n;i++) ans[i].clear ();
V.clear ();
M.clear ();
memset (head,-1,sizeof (head));
cnt=0;
while (m--) {string A, B;
cin>>a>>b; if (!
M.count (a)) {v.push_back (a);
M[a]=v.size (); } if (!
M.count (b)) {v.push_back (b);
M[b]=v.size ();
} Add (M[a],m[b]);
} int Sig=tarjan (n);
for (int i=0;i<v.size (); i++) Ans[scc[m[v[i]]]].push_back (V[i]);
Sort (ans+1,ans+n+1); if (t++) printF ("\ n");
printf ("Calling circles for data set%d:\n", t);
for (int i=1;i<=n;i++) if (Ans[i].size ()) {for (int j=0;j<ans[i].size (); j + +) {
if (j) printf (",");
cout<<ans[i][j];
} cout<<endl; }
}
}