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 }