日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

P1477-[NOI2008]假面舞会【构图,dfs,gcd】

發布時間:2023/12/3 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 P1477-[NOI2008]假面舞会【构图,dfs,gcd】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

正題

題目鏈接:https://www.luogu.org/problem/P1477


題目大意

一張有向圖,分為zzz類點,對于每條邊要么是iii類連向i+1i+1i+1類,要么是kkk類連向111類(k≥3k\geq 3k3),求zzz的最小值和最大值(不給出kkk)


解題思路

首先不考慮環,那么最大值就是每張圖中最長鏈的長度和,最小值就是333,因為1?>2?>3?>1...1->2->3->1...1?>2?>3?>1...就好了。

若有環,最大值就是每個環大小的gcdgcdgcd,因為對于每個環都要分成若干個相同長度的循環節,然后最小值就是最大值的一個最小的因子(要≥3\geq 33),因為這是可以分成的最小循環節。

dfsdfsdfs找就好了。


codecodecode

#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e5+10; struct node{int to,next,w; }a[20*N]; int n,m,ans,minans,maxans,dis[N],ls[N],tot; bool v[N]; void addl(int x,int y,int w) {a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;a[tot].w=w; } void circle(int x) {v[x]=1;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(v[y]) ans=__gcd(ans,abs(dis[x]-dis[y]+a[i].w));else dis[y]=dis[x]+a[i].w,circle(y);} } void line(int x) {v[x]=1;minans=min(minans,dis[x]);maxans=max(maxans,dis[x]);for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(v[y]) continue;dis[y]=dis[x]+a[i].w;line(y);} } int main() {scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);addl(x,y,1);addl(y,x,-1);}for(int i=1;i<=n;i++)if(!v[i]) circle(i);if(ans){if(ans<3){printf("-1 -1\n");return 0;}for(int i=3;i<=ans;i++)if(!(ans%i)){minans=i;break;}printf("%d %d\n",ans,minans);return 0;}memset(dis,0,sizeof(dis));memset(v,0,sizeof(v));for(int i=1;i<=n;i++)if(!v[i]){minans=maxans=0;line(i);ans+=maxans-minans+1;}if(ans<3) printf("-1 -1\n");else printf("%d 3\n",ans); }

總結

以上是生活随笔為你收集整理的P1477-[NOI2008]假面舞会【构图,dfs,gcd】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。