這道題就是很簡單的bfs,可以觀察到n變化到m是近似成倍增長的。其實從最小到最大的變化也就只有30次而已。
這是一道好題,資料很大,但邊是雙向的,只是刪一條邊或乙個點,而且保證了點兩兩之間是連通的。(這些很重要)#include
#include
#include
typedef
long
long ll;
using
namespace
std;
const
int maxl=100;
const
int oo=1e9;
const
int n=100000;
int t,n,m;
int op[n+10],ct,ch,f[n+10];
bool uss[n+10];
int main()
if(i*i!=op[ct])}}
}}uss[op[ch]]=0;
ch++;
}printf("%d\n",(f[m]!=oo)?f[m]:-1);
}return
0;}
那麼,可以從dfs序入手,dfs序是一棵樹,其中會有返祖邊。(如圖)
那我們只需要判斷刪掉的點或邊是否在u到v的路徑上,不在的話,刪了也沒用。(用三次lca處理)。
如果刪的是邊,判斷邊的左右端點是否為乙個塊,(dfn[a]>dfn[b] 且 low[a]≤dfn[b])是的話,刪了還是u,v保持連通的,否則u,v不連通,(必經路被刪)
如果刪的是點c。lca—u,v的公共祖先
若c在u->lca的路徑上,則更新uminlow(能到達的最早的點)。
若c在v->lca的路徑上,則更新vminlow(能到達的最早的點)。
判斷uminlow和vminlow都小於c就保證了u,v之間連通。
否則不連通。
一道貪心的題目。#include
#include
#include
#define imax(a,b) ((a>b)?(a):(b))
#define imin(a,b) ((atypedef
long
long ll;
using
namespace
std;
const
int mm=500100;
const
int nn=100100;
int n,e,q,dt,tn;
bool vis[nn];
int ti[nn],low[nn];
int ne[mm<<1],to[mm<<1],h[nn],tt;
int f[nn][20];
void addedge(int a,int b)
void dfs(int x,int fa)
}int lca(int a,int b)
int mingo(int a,int b)
bool judge(int u,int v,int a)
int main()
ti[0]=low[0]=0; dt=0; dfs(1,0);
f[1][0]=1; tn=0;
for(int i=1;(1
<
f[j][i]=f[f[j][i-1]][i-1];
}scanf("%d",&q);
for(int i=1;i<=q;i++)
else
printf("yes\n");
} else
if(ww==2)
else
} else
printf("yes\n");}}
return
0;}
假設不是乙個環,而是一條鏈,那該怎麼做?
很顯然,低-高-低這類是不可能的,因為低-低-高肯定比它更優。
是環的話,最低-最高這肯定是不行的,因為需要最大的最小。
可以考慮數列拆成兩部分(排序後按a5-a3-a1-a2-a4-a6這樣排)。
這樣是最優的,詳細證明如下:
a5-a3-a1-a2-a4-a6,假設a4-a6最大,可以改得更優,a5移過來,變成a3-a1-a2-a4-a5-a6,那麼a3-a6比a4-a6跟大,答案肯定不會優。
其他情況也差不多。
ai和ai+1之間肯定改不了(-_-|| 顯然的)。
字典序怎麼辦?先求出minans,然後放a1,在右側放a2,判斷a4和當前頭的距離是否合法(小於等於minans),不合法的話a3只能放在頭的左側作為新的頭(不合法的話,再將a3放在右側的話,a4就沒法放了 放左或放右都會使最大距離大於minans),合法的話就將a3放在右側,以此類推。
考的不怎麼好,沒狀態,最後一題想出來但字典序問題沒搞好。爭取在每一次考試中都能不斷進步吧!#include
#include
#include
#include
#define imax(a,b) ((a>b)?(a):(b))
typedef
long
long ll;
using
namespace
std;
bool cmp(int a,int b)
ans=abs(p[1]-p[n]);
for(int i=2;i<=n;i++) ans=imax(ans,abs(p[i]-p[i-1]));
l1=1; l2=1;
ya[1]=d[1]; yb[1]=d[1];
for(int i=2;i<=n;i++)
for(int i=1;i<=l1;i++) printf("%d ",ya[i]);
for(int i=l2;i>=2;i--) printf("%d ",yb[i]); printf("\n");
}return
0;}
超越自己,讓自己變得更好 ————加油,努力
NOIP2017提高組模擬賽5 (總結)
其實就是將乙個點f拆成向左l向右r的兩個點,然後將所有點排序 不用排序也行,直接找 選第乙個l,從後往前選第乙個不與l同乙個f的r。選最後乙個r,從前往後選第乙個不與r同乙個f的l。答案中的最大值即為兩點之間的最遠距離。證明如下 0 數學方法 把01看成a b個點。設s a b,x 最少要翻轉次數,...
NOIP2017提高組 模擬賽21(總結)
題目描述 解題思路 問題轉化為有多少個 l,r 使得a的l r這個區間乘起來是k的倍數。k 的時間分解k的質因數。列舉l,可以發現r具有單調性,也就是若 l,r 合法,那麼 l,r 1 也合法。用尺取法就可以解決。時間複雜度 o 2n k include include using namespac...
NOIP2017提高組 模擬賽 26(總結)
題目描述 解題思路 構造法 假設現在有m個點,刪除乙個點,剩下的m 1個點都已經確定,那麼刪除的這個點應該染什麼顏色。假如這個點所在的行的點數為奇數,那麼點的染色只與它所在的列有關 若列有偶數個點,那麼這個點的顏色就可以確定了,哪種顏色少選哪種。否則隨便選 假如這個點所在的列的點數為奇數,與上面類似...