P1477-[NOI2008]假面舞会【构图,dfs,gcd】
生活随笔
收集整理的這篇文章主要介紹了
P1477-[NOI2008]假面舞会【构图,dfs,gcd】
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
正題
題目鏈接:https://www.luogu.org/problem/P1477
題目大意
一張有向圖,分為zzz類點(diǎn),對(duì)于每條邊要么是iii類連向i+1i+1i+1類,要么是kkk類連向111類(k≥3k\geq 3k≥3),求zzz的最小值和最大值(不給出kkk)
解題思路
首先不考慮環(huán),那么最大值就是每張圖中最長鏈的長度和,最小值就是333,因?yàn)?span id="ze8trgl8bvbq" class="katex--inline">1?>2?>3?>1...1->2->3->1...1?>2?>3?>1...就好了。
若有環(huán),最大值就是每個(gè)環(huán)大小的gcdgcdgcd,因?yàn)閷?duì)于每個(gè)環(huán)都要分成若干個(gè)相同長度的循環(huán)節(jié),然后最小值就是最大值的一個(gè)最小的因子(要≥3\geq 3≥3),因?yàn)檫@是可以分成的最小循環(huán)節(jié)。
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); }總結(jié)
以上是生活随笔為你收集整理的P1477-[NOI2008]假面舞会【构图,dfs,gcd】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑看电影配置推荐(电脑看电影配置)
- 下一篇: 牛客小白月赛18-记录