PAT 2019-3 7-3 Telefraud Detection

Description:

Telefraud(电信诈骗) remains a common and persistent problem in our society. In some cases, unsuspecting victims lose their entire life savings. To stop this crime, you are supposed to write a program to detect those suspects from a huge amount of phone call records.

A person must be detected as a suspect if he/she makes more than K short phone calls to different people everyday, but no more than 20% of these people would call back. And more, if two suspects are calling each other, we say they might belong to the same gang. Amakes a short phone call to B means that the total duration of the calls from A to B is no more than 5 minutes.

Input Specification:

Each input file contains one test case. For each case, the first line gives 3 positive integers K (≤, the threshold(阈值) of the amount of short phone calls), N (≤, the number of different phone numbers), and M (≤, the number of phone call records). Then M lines of one day's records are given, each in the format:

caller receiver duration

where caller and receiver are numbered from 1 to N, and duration is no more than 1440 minutes in a day.

Output Specification:

Print in each line all the detected suspects in a gang, in ascending order of their numbers. The gangs are printed in ascending order of their first members. The numbers in a line must be separated by exactly 1 space, and there must be no extra space at the beginning or the end of the line.

If no one is detected, output None instead.

Sample Input 1:

5 15 31
1 4 2
1 5 2
1 5 4
1 7 5
1 8 3
1 9 1
1 6 5
1 15 2
1 15 5
3 2 2
3 5 15
3 13 1
3 12 1
3 14 1
3 10 2
3 11 5
5 2 1
5 3 10
5 1 1
5 7 2
5 6 1
5 13 4
5 15 1
11 10 5
12 14 1
6 1 1
6 9 2
6 10 5
6 11 2
6 12 1
6 13 1

Sample Output 1:

3 5
6

Note: In sample 1, although 1 had 9 records, but there were 7 distinct receivers, among which 5 and 15 both had conversations lasted more than 5 minutes in total. Hence 1 had made 5 short phone calls and didn't exceed the threshold 5, and therefore is not a suspect.

Sample Input 2:

5 7 8
1 2 1
1 3 1
1 4 1
1 5 1
1 6 1
1 7 1
2 1 1
3 1 1

Sample Output 2:

None

Keys:

  • 模拟题

Attention:

  • A1034的升级版

Code:

  1 /*
  2 嫌疑人:与超过K个不同的人拨打短电话(通话总时长<=5),但是<=20%的人回复电话
  3 犯罪团伙:两个嫌疑人之间互通电话
  4 
  5 阈值K<=500,通话人数N<=1e3,通话记录数量M<=1e5
  6 打电话者(1~N),接电话者,通话时长
  7 
  8 按行打印犯罪团伙(第一个嫌疑人的序号递增
  9 嫌疑人按照序号递增,
 10 
 11 基本思路:
 12 图存储,通话总时长
 13 二重循环遍历图一次,记录每个人往外拨打短电话的人数,并统计其中回复的人数
 14 如果,超过K个人,并且回复的人数re<=0.2*call -> 5*re <= call,认定为嫌疑人
 15 存储至嫌疑人队列
 16 
 17 二重循环遍历嫌疑人队列,判断任意两个人是否有过通话
 18 如果有,则Union,并领较小者为父亲结点
 19 
 20 再次遍历嫌疑人队列,存储头目,以头目为下标,存储团伙成员
 21 
 22 打印,遍历头目,输出团伙成员
 23 */
 24 #include<cstdio>
 25 #include<vector>
 26 #include<set>
 27 using namespace std;
 28 const int M=1e3+10;
 29 int grap[M][M],father[M];
 30 vector<int> gang[M];
 31 
 32 int Find(int v)
 33 {
 34     int s=v;
 35     while(v != father[v])
 36         v=father[v];
 37     while(s != father[s])
 38     {
 39         int x = father[s];
 40         father[s] = v;
 41         s = x;
 42     }
 43     return v;
 44 }
 45 
 46 void Union(int s1, int s2)
 47 {
 48     int f1=Find(s1);
 49     int f2=Find(s2);
 50     if(f1<f2)
 51         father[f2]=f1;
 52     else
 53         father[f1]=f2;
 54 }
 55 
 56 int main()
 57 {
 58 #ifdef ONLINE_JUDGE
 59 #else
 60     freopen("Test.txt", "r", stdin);
 61 #endif // ONLINE_JUDEG
 62 
 63     fill(grap[0],grap[0]+M*M,0);
 64     for(int i=0; i<M; i++)
 65         father[i]=i;
 66 
 67     int k,n,m;
 68     scanf("%d%d%d", &k,&n,&m);
 69     for(int i=0; i<m; i++)
 70     {
 71         int v1,v2,w;
 72         scanf("%d%d%d", &v1,&v2,&w);
 73         grap[v1][v2] += w;
 74     }
 75     vector<int> suspect;
 76     for(int i=1; i<=n; i++)
 77     {
 78         int call=0,re=0;
 79         for(int j=1; j<=n; j++)
 80         {
 81             if(grap[i][j]!=0 && grap[i][j]<=5)
 82             {
 83                 call++;
 84                 if(grap[j][i]!=0)
 85                     re++;
 86             }
 87         }
 88         if(call>k && 5*re<=call)
 89             suspect.push_back(i);
 90     }
 91     for(int i=0; i<suspect.size(); i++)
 92     {
 93         for(int j=i+1; j<suspect.size(); j++)
 94         {
 95             int s1=suspect[i],s2=suspect[j];
 96             if(grap[s1][s2]!=0 && grap[s2][s1]!=0)
 97                 Union(s1,s2);
 98         }
 99     }
100     set<int> head;
101     for(int i=0; i<suspect.size(); i++)
102     {
103         int s = Find(suspect[i]);
104         head.insert(s);
105         gang[s].push_back(suspect[i]);
106     }
107     if(head.size()==0)
108         printf("None");
109     else
110     {
111         for(auto it=head.begin(); it!=head.end(); it++)
112             for(int i=0; i<gang[*it].size(); i++)
113                 printf("%d%c", gang[*it][i],i==gang[*it].size()-1?'\n':' ');
114     }
115 
116     return 0;
117 }

 

posted @ 2019-09-01 19:49  林東雨  阅读(599)  评论(0编辑  收藏  举报