T1  重量不同的硬币

有N(1 <= N <= 1,000)个硬币,编号为1..N。

给出W(1 <= W <= 3,000)个推断对(A,B),表示硬币A比硬币B重。

寻找并输出一个硬币编号,要求其重量明确不同于其他硬币的个数最多。如果有多个答案,输出编号最小的一个。如果给出的数据有矛盾,输出"IMPOSSIBLE"

PROBLEM NAME: coins

INPUT FORMAT:

* Line 1: 两个整数: N and W.

* Lines 2..W+1: 每行两个整数: A, B

OUTPUT FORMAT:

* Line 1: 重量不同于其他硬币的个数最多的硬币编号。

【题解】

根据题意建图,注意正反图都要建(蒟蒻考试时没有建反图,挂掉)

如果图中有环,显然是"IMPOSSIBLE",所以先用tarjan判环。

然后两遍dfs遍历,找到每个结点的子树大小,输出最大的编号就行了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<ctime>
 7 #include<algorithm>
 8 #include<queue>
 9 using namespace std;
10 #define INF 1000000000
11 #define MAXN 3010
12 struct node{int y,next,v;}e[MAXN*2];
13 int n,m,len,ans,now,bcnt,top,maxx,Link[MAXN],stack[MAXN],inst[MAXN],vis[MAXN],dfn[MAXN],low[MAXN],belong[MAXN],cnt1[MAXN],cnt2[MAXN];
14 inline int read()
15 {
16     int x=0,f=1;  char ch=getchar();
17     while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
18     while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
19     return x*f;
20 }
21 void insert(int x,int y,int v)
22 {
23     e[++len].next=Link[x];
24     Link[x]=len;
25     e[len].y=y;
26     e[len].v=v;
27 }
28 void tarjan(int x)
29 {
30     dfn[x]=low[x]=++now;
31     stack[++top]=x;  inst[x]=1;
32     for(int i=Link[x];i;i=e[i].next)
33         if(e[i].v)
34         {
35             if(!dfn[e[i].y])
36             {
37                 tarjan(e[i].y);
38                 low[x]=min(low[x],low[e[i].y]);
39             }
40             else if(inst[e[i].y]) low[x]=min(low[x],dfn[e[i].y]);
41         }
42     if(dfn[x]==low[x])
43     {
44         int y;  bcnt++;
45         do
46         {
47             y=stack[top--];
48             inst[y]=0;
49             belong[y]=bcnt;
50         }while(y!=x);
51     }
52 }
53 void dfs1(int x)
54 {
55     cnt1[x]=1;  vis[x]=1;
56     for(int i=Link[x];i;i=e[i].next)
57         if(!vis[e[i].y]&&e[i].v)
58         {
59             dfs1(e[i].y);
60             cnt1[x]+=cnt1[e[i].y];
61         }
62 }
63 void dfs2(int x)
64 {
65     cnt2[x]=1;  vis[x]=1;
66     for(int i=Link[x];i;i=e[i].next)
67         if(!vis[e[i].y]&&!e[i].v)
68         {
69             dfs2(e[i].y);
70             cnt2[x]+=cnt2[e[i].y];
71         }
72 }
73 int main()
74 {
75     freopen("coins.in","r",stdin);
76     freopen("coins.out","w",stdout);
77     n=read();  m=read();
78     for(int i=1;i<=m;i++)
79     {
80         int x=read(),y=read();
81         insert(x,y,1);  insert(y,x,0);
82     }
83     for(int i=1;i<=n;i++)  if(!dfn[i])  tarjan(i);
84     for(int i=1;i<=n;i++)  
85     {
86         if(vis[belong[i]])  {printf("IMPOSSIBLE\n");  return 0;}
87         else vis[belong[i]]=1;
88     }
89     for(int i=1;i<=n;i++)
90     {
91         memset(vis,0,sizeof(vis));
92         dfs1(i);
93         memset(vis,0,sizeof(vis));
94         dfs2(i);
95         if(cnt1[i]+cnt2[i]>maxx)  {maxx=cnt1[i]+cnt2[i];  ans=i;}
96     }
97     printf("%d\n",ans);
98     return 0;
99 }
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-15
  • 2022-12-23
  • 2022-12-23
  • 2021-08-22
  • 2021-10-01
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-11-22
  • 2021-06-01
  • 2021-08-17
相关资源
相似解决方案