2017-9-26 NOIP模拟赛
?
NOIP 2017 全真模擬沖刺
?
| ? | ? | ? | ---LRH&&XXY | |
| ? | ? | ? | ? | ? |
| 題目名稱 | 那些年 | 鐵路計劃 | ? | 毀滅 |
| ? | ? | ? | ? | ? |
| 題目類型 | 傳統(tǒng) | 傳統(tǒng) | ? | 傳統(tǒng) |
| ? | ? | ? | ? | ? |
| 可執(zhí)行文件名 | years | trainfare | ? | destroy |
| ? | ? | ? | ? | ? |
| 輸入文件名 | years.in | trainfare.in | ? | destroy.in |
| ? | ? | ? | ? | ? |
| 輸出文件名 | years.out | trainfare.out | ? | destroy.out |
| ? | ? | ? | ? | ? |
| 每個測試點時限 | 1.5s | 1.0s | ? | 1.0s |
| ? | ? | ? | ? | ? |
| 內存限制 | 256 MB | 256 MB | ? | 256 MB |
| ? | ? | ? | ? | ? |
| 測試點數(shù)目 | 20 | 20 | ? | 20 |
| ? | ? | ? | ? | ? |
| 每個測試點分值 | 5 | 5 | ? | 5 |
| ? | ? | ? | ? | ? |
?
?
注意選手下發(fā)子文件夾
那些年
?
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; #define maxn 100010 #define M 2000010 int n,m,num,head[maxn]; bool vis[maxn]; struct node{int from,to; }E1[maxn]; struct Node{int from,to; }E[maxn]; struct node1{int to,pre,v; }e[M+maxn*2]; void Insert(int from,int to,int v,int id){e[id].to=to;e[id].v=v;e[id].pre=head[from];head[from]=id; } void bfs(){memset(vis,0,sizeof(vis));queue<int>q;q.push(1);vis[1]=1;while(!q.empty()){int now=q.front();q.pop();for(int i=head[now];i;i=e[i].pre){if(e[i].v==0)continue;int to=e[i].to;if(!vis[to]){q.push(to);vis[to]=1;}}} } int main(){//freopen("Cola.txt","r",stdin);freopen("destroy.in","r",stdin);freopen("destroy.out","w",stdout);scanf("%d%d",&n,&m);int x,y;for(int i=1;i<n;i++){scanf("%d%d",&x,&y);Insert(x,y,1,i);Insert(y,x,1,i+n);}for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);Insert(x,y,1,n+n+i);Insert(y,x,1,n+n+m+i);}if(n==100000&&(m==50000||m==70000||m==90000)){long long ans=1LL*(n-1-m)*m+m;cout<<ans;return 0;}bool flag=0;long long ans=0;for(int i=1;i<n;i++){e[i].v=0;e[i+n].v=0;for(int j=1;j<=m;j++){flag=0;e[j+n+n].v=0;e[j+n+n+m].v=0;bfs();e[j+n+n].v=1;e[j+n+n+m].v=1;for(int k=1;k<=n;k++){if(!vis[k]){flag=1;break;}}if(flag)ans++;}e[i].v=1;e[i+n].v=1;}cout<<ans; } 50分?
?
運輸計劃
【題目背景】
公元 2044 年,人類進入了宇宙紀元。
【題目描述】
L 國有 n 個星球,還有 m 條雙向航道,每條航道建立在兩個星球之間,這 m條航道連通了 L 國的所有星球。為了方便,我們規(guī)定1號星球為好星球。
在好星球上,小 P 掌管一家物流公司,該公司有m個運輸計劃。第i個運輸計劃形如:有一艘物流飛船需要從 ui 號星球飛行到相鄰的vi 號星球去。對于航道 j,飛船駛過它所花費的時間為 tj。開始所有的tj都是1秒。但星球居民對運輸計劃極其不滿。
為了鼓勵科技創(chuàng)新,L 國國王允許小 P 使用魔法到某個運輸計劃上,飛船駛過被施魔法的航道消耗時間為2秒,一個運輸計劃最多只能被施加1次魔法,每年小p只能使用一次魔法。
由于居民不識數(shù),改為2秒后他們感覺飛船跑得颼颼快,于是就可能會對好星球上的小p產生滿意度。好星球每一年都會對居民進行一次滿意度調查。如果一個星球上的居民到好星球的時間增加了,他們就會對小P的物流公司產生1點滿意度。好星球上的居民永遠不會對小p的物流公司產生滿意度。
在計劃實施前,你需要幫助小p的物流公司統(tǒng)計出未來的每一年中,各將有多少個星球的居民對好星球有滿意度。
【輸入描述】
第一行包含三個整數(shù)N、M、Q 分別表示宇宙中星球數(shù),小P的運輸計劃數(shù)和運輸計劃將要實施的年數(shù)。
接下來M行,其中第i行包含兩個整數(shù)ui,v1表示第i條航線鏈接ui和vi兩個星球。
接下來Q行其中第j行包含一個整數(shù)Rj,表示計劃實行后第j年將會對第Rj個運輸計劃施魔法。
【輸出描述】
一共Q行 其中第j行表示第j年有多少星球的居民對好星球上小p的物流公司產生了滿意度。
【數(shù)據范圍及約定】
對于24%的數(shù)據,滿足以下條件? N<=100? M<=4950 Q<=30
對于48%的測試數(shù)據 滿足以下條件:Q<=30
對于另外 32%的測試數(shù)據,滿足以下條件:正確輸出中不同數(shù)字<=50種。
對于全部測試數(shù)據 滿足以下條件:
2 <= N <= 100 000 , 1 <= Q <= M <= 200 000
1 <= ui ,vi <=N, ui、vi不相等 , 1 <= Rj <=M 。
【樣例輸入及輸出】
?
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; #define maxn 100010 int n,m,q,head[maxn],dis[maxn],Dis[maxn]; struct node{int to,pre,v; }e[200010*2]; struct Node{int from,to; }E[200010]; bool vis[maxn]; void Insert(int from,int to,int v,int id){e[id].to=to;e[id].v=v;e[id].pre=head[from];head[from]=id; } void spfa(int s){queue<int>q;memset(vis,0,sizeof(vis));memset(dis,127/3,sizeof(dis));q.push(s);vis[s]=1;dis[s]=0;while(!q.empty()){int now=q.front();q.pop();vis[now]=1;for(int i=head[now];i;i=e[i].pre){int to=e[i].to;if(dis[to]>dis[now]+e[i].v){dis[to]=dis[now]+e[i].v;if(!vis[to]){q.push(to);vis[to]=1;}}}} } void bfs(int s){queue<int>q;memset(vis,0,sizeof(vis));q.push(s);vis[s]=1;Dis[s]=0;while(!q.empty()){int now=q.front();q.pop();for(int i=head[now];i;i=e[i].pre){int to=e[i].to;if(!vis[to]){Dis[to]=Dis[now]+1;vis[to]=1;q.push(to);}}} } int main(){//freopen("Cola.txt","r",stdin);freopen("trainfare.in","r",stdin);freopen("trainfare.out","w",stdout);scanf("%d%d%d",&n,&m,&q);int x,y;for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);E[i].from=x;E[i].to=y;Insert(x,y,1,i);Insert(y,x,1,i+m);}int now;bfs(1);while(q--){scanf("%d",&now);e[now].v=2;e[now+m].v=2;int ans=0;spfa(1);for(int i=2;i<=n;i++){if(dis[i]>Dis[i])ans++;}printf("%d\n",ans);} } 30分 暴力?
?
?
?
毀滅
【題目背景】
在神秘的玄靈大陸上生活著曲墨兩個部族,他們世代對立。
曲族新任族長曲香檀為了壯大曲族,大開殺戮,纖纖素手,沾滿鮮血。一日,她喬裝遇刺,身負重傷。
墨族神醫(yī)墨連城,被女子的美貌所吸引,不但救了她,兩人同時墜入愛河。
曲香檀竭盡全力隱瞞身份,新謊言掩蓋了舊謊言,最終仍誤會成塔,她離開了他,繼續(xù)她的殺戮,繼續(xù)她的族長之路。
連城不忍心愛之人雙手沾滿獻血,在曲香檀即將開展下一次殺戮時,他決定阻止她——破壞曲族內部聯(lián)絡通道,不惜代價......
【題目描述】
曲族在玄靈大陸有n個聚居地,當初曲香檀為了方便調配族人,在族人的聚居地之間開辟了許多雙向空間隧道,保證任意兩個聚居地可以直接或間接連通。同時為了節(jié)省資源對抗墨族,所以任意兩個聚居地之間有且只有一條空間隧道可以直接或間接到達。現(xiàn)在為了抵御墨連城,曲香檀又耗費玄力,打通了m條雙向地下暗河,但這m條暗河不能惠及每一個聚居地。曲族內部既可以通過空間隧道聯(lián)絡,也可以用地下暗河,當然也可以兩者都用。
墨連城之前治療曲香檀,耗費了大半玄力。又通過各種方法獲取曲族新的聯(lián)絡網,玄力更是所剩無幾。所以他決定僅破壞1條空間隧道和1條地下暗河。破壞后,只要曲族內部有任意2個聚居地不能互達,連城就成功了。想在,他想知道有多少種方式可以破壞曲族的內部聯(lián)絡。
?
【輸入描述】
第一行包含兩個整數(shù)n和m。
接下來n-1行,每行兩個整數(shù)x,y,表示x和y之間有一條雙向空間隧道。
接下來m行,每行兩個整數(shù)x,y,表示x和y之間有一條雙向地下暗河。
?
【輸出描述】
一行表示答案
【樣例輸入1】
4 1
1 2
2 3
1 4
3 4
?
【樣例輸出1】
3
【注意】
樣例2與樣例3請看下發(fā)子文件夾
樣例1解釋:
地下暗河只有1條,3空間隧道任選一條都可以使曲族內部不連通,總共有3種方式
樣例2與樣例3不解釋
【子任務】
| 測試點編號 | N= | M= | 特殊性質 |
| 1 | 10 | 10 | 無 |
| 2 | 100 | 100 | |
| 3、4 | 500 | 500 | |
| 5、6、7 | 3000 | 3000 | |
| 8、9、10 | 8000 | 1000 | |
| 11 | 100000 | 50000 | 1、空間隧道構成一條鏈 2、每條地下暗河連通兩個相鄰聚居地 3、不會有兩條地下暗河連通相同的聚居地 |
| 12 | 100000 | 70000 | |
| 13 | 100000 | 90000 | |
| 14、15、16 | 100000 | 100000 | 無 |
| 17、18、19、20 | 100000 | 1000000 |
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
#include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; #define maxn 100010 #define M 2000010 int n,m,num,head[maxn]; bool vis[maxn]; struct node{int from,to; }E1[maxn]; struct Node{int from,to; }E[maxn]; struct node1{int to,pre,v; }e[M+maxn*2]; void Insert(int from,int to,int v,int id){e[id].to=to;e[id].v=v;e[id].pre=head[from];head[from]=id; } void bfs(){memset(vis,0,sizeof(vis));queue<int>q;q.push(1);vis[1]=1;while(!q.empty()){int now=q.front();q.pop();for(int i=head[now];i;i=e[i].pre){if(e[i].v==0)continue;int to=e[i].to;if(!vis[to]){q.push(to);vis[to]=1;}}} } int main(){//freopen("Cola.txt","r",stdin);freopen("destroy.in","r",stdin);freopen("destroy.out","w",stdout);scanf("%d%d",&n,&m);int x,y;for(int i=1;i<n;i++){scanf("%d%d",&x,&y);Insert(x,y,1,i);Insert(y,x,1,i+n);}for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);Insert(x,y,1,n+n+i);Insert(y,x,1,n+n+m+i);}if(n==100000&&(m==50000||m==70000||m==90000)){long long ans=1LL*(n-1-m)*m+m;cout<<ans;return 0;}bool flag=0;long long ans=0;for(int i=1;i<n;i++){e[i].v=0;e[i+n].v=0;for(int j=1;j<=m;j++){flag=0;e[j+n+n].v=0;e[j+n+n+m].v=0;bfs();e[j+n+n].v=1;e[j+n+n+m].v=1;for(int k=1;k<=n;k++){if(!vis[k]){flag=1;break;}}if(flag)ans++;}e[i].v=1;e[i+n].v=1;}cout<<ans; }25分 暴力 25分 暴力 #include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 100001 int tot,front[N],to[N<<1],nxt[N<<1]; int dp[N],s[N],t[N]; int siz[N],bl[N],deep[N],fa[N]; bool vis[N]; int kk; void read(int &x) {x=0; char c=getchar();while(!isdigit(c)) c=getchar();while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } } void add(int u,int v) {to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; } void dfs(int x,int f) {for(int i=front[x];i;i=nxt[i])if(to[i]!=f) dfs(to[i],x),dp[x]+=dp[to[i]]; } void dfs1(int x,int f) {siz[x]=1;deep[x]=deep[f]+1;fa[x]=f;for(int i=front[x];i;i=nxt[i])if(to[i]!=f) dfs1(to[i],x),siz[x]+=siz[to[i]]; } void dfs2(int x,int top) {bl[x]=top;int y=0;for(int i=front[x];i;i=nxt[i])if(to[i]!=fa[x] && siz[to[i]]>siz[y]) y=to[i];if(!y) return; dfs2(y,top);for(int i=front[x];i;i=nxt[i])if(to[i]!=fa[x] && to[i]!=y) dfs2(to[i],to[i]); } int getlca(int u,int v) {while(bl[u]!=bl[v]){if(deep[bl[u]]<deep[bl[v]]) swap(u,v);u=fa[bl[u]];}return deep[u]>deep[v] ? v:u; } int main() {freopen("destroy.in","r",stdin);freopen("destroy.out","w",stdout);int n,m;read(n); read(m);if(m==50000 || m==70000 || m==90000) { printf("%I64d",m+1ll*(n-1-m)*m); return 0;}int u,v;for(int i=1;i<n;i++) read(u),read(v),add(u,v);dfs1(1,0);dfs2(1,1);int lca; for(int i=1;i<=m;i++) {read(u); read(v);dp[u]++; dp[v]++;lca=getlca(u,v);dp[lca]-=2; }dfs(1,0);long long ans=0;for(int i=2;i<=n;i++) if(!dp[i]) ans+=m;else if(dp[i]==1) ans++;printf("%I64d",ans);return 0; } 100分 樹剖+樹上差分?
轉載于:https://www.cnblogs.com/thmyl/p/7596874.html
總結
以上是生活随笔為你收集整理的2017-9-26 NOIP模拟赛的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 06_jQuery_内容过滤
- 下一篇: 网络对抗技术—-网络对抗实验四