NOIP模拟2
期望得分:100+100+100=300
实际得分:70+40+20=130
T1 [SCOI2007]kshort弱化版
Description
有n个城市和m条单向道路,城市编号为1~n。每条道路连接两个不同的城市,且任意两条道路要么起点不同要么终点不同,因此n和m满足m<=n(n-1)。给定两个城市a和b,可以给a到b的所有简单路(所有城市最多经过一次,包括起点和终点)排序:先按长度从小到大排序,长度相同时按照字典序从小到大排序。你的任务是求出a到b的第k短路。
Input
输入第一行包含五个正整数n, m, k, a, b。以下m行每行三个整数u, v, l,表示从城市u到城市v有一条长度为l的单向道路。100%的数据满足:2<=n<=50, 1<=k<=200
Output
如果a到b的简单路不足k条,输出No,否则输出第k短路:从城市a开始依次输出每个到达的城市,直到城市b,中间用减号"-"分割。
基本思路:A*跑k短路,二进制压缩判重
考场思路:重载运算符比较字典序
错因:spfa判重数组vis,用了边权数组val
另一种方式:记录所有长度<=第k短长度的路径,取第k条
记录路径的时候,定义vector<结构体>,直接sort
vector是从0开始的!!!!
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#define N 51
using namespace std;
int n,m,k,a,b,sum;
short front[N],nxt[N*N],to[N*N],tot;
short front2[N],nxt2[N*N],to2[N*N],tot2;
int val[N*N],val2[N*N],dis[N];
queue<int>q;
struct node
{
int num,dis2;
long long go;
short cnt,road[N];
bool operator < (node p) const
{
if(dis2+dis[num]!=p.dis2+dis[p.num]) return dis2+dis[num]>p.dis2+dis[p.num];
for(int i=;i<=min(cnt,p.cnt);i++)
if(road[i]!=p.road[i]) return road[i]>p.road[i];
return cnt>p.cnt;
}
}cur,nt;
priority_queue<node>q2;
bool vis[N];
void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
void add(int u,int v,int w)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w;
to2[++tot2]=u; nxt2[tot2]=front2[v]; front2[v]=tot2; val2[tot2]=w;
}
void spfa()
{
memset(dis,,sizeof(dis));
dis[b]=; vis[b]=true; q.push(b);
int now;
while(!q.empty())
{
now=q.front(); q.pop(); vis[now]=false;
for(int i=front[now];i;i=nxt[i])
if(dis[to[i]]>dis[now]+val[i])
{
dis[to[i]]=dis[now]+val[i];
if(!vis[to[i]])
{
vis[to[i]]=true;
q.push(to[i]);
}
}
}
}
bool have(long long x,int y)
{
if(x&(1LL<<y)) return true;
return false;
}
void solve()
{
if(dis[a]>2e9)
{
printf("No");
return;
}
if(a==b) k++;
cur.cnt=;
cur.dis2=;
cur.go=1LL<<a;
cur.num=cur.road[]=a;
q2.push(cur);
while(!q2.empty())
{
cur=q2.top(); q2.pop();
if(cur.num==b)
{
sum++;
if(sum==k)
{
printf("%d",a);
for(int i=;i<=cur.cnt;i++) printf("-%d",cur.road[i]);
return;
}
}
for(int i=front2[cur.num];i;i=nxt2[i])
if(!have(cur.go,to2[i]))
{
nt.cnt=cur.cnt+;
nt.dis2=cur.dis2+val2[i];
nt.go=cur.go|(1LL<<to2[i]);
nt.num=to2[i];
for(int j=;j<=cur.cnt;j++) nt.road[j]=cur.road[j];
nt.road[nt.cnt]=to2[i];
q2.push(nt);
}
}
printf("No");
}
int main()
{
//freopen("bzoj_1073.in","r",stdin);
//freopen("bzoj_1073.out","w",stdout);
read(n); read(m); read(k); read(a); read(b);
int u,v,w;
while(m--)
{
read(u); read(v); read(w);
add(v,u,w);
}
spfa();
solve();
}
#include<queue>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define N 51
using namespace std;
int n,m,k,a,b,sum;
short front[N],nxt[N*N],to[N*N],tot;
short front2[N],nxt2[N*N],to2[N*N],tot2;
int val[N*N],val2[N*N],dis[N];
queue<int>q;
struct node
{
int num,dis2;
long long go;
short cnt,road[N];
bool operator < (node p) const
{
return dis2+dis[num]>p.dis2+dis[p.num];
}
}cur,nt;
vector<node>ans;
priority_queue<node>q2;
bool vis[N];
void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
void add(int u,int v,int w)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; val[tot]=w;
to2[++tot2]=u; nxt2[tot2]=front2[v]; front2[v]=tot2; val2[tot2]=w;
}
void spfa()
{
memset(dis,,sizeof(dis));
dis[b]=; vis[b]=true; q.push(b);
int now;
while(!q.empty())
{
now=q.front(); q.pop(); vis[now]=false;
for(int i=front[now];i;i=nxt[i])
if(dis[to[i]]>dis[now]+val[i])
{
dis[to[i]]=dis[now]+val[i];
if(!vis[to[i]])
{
vis[to[i]]=true;
q.push(to[i]);
}
}
}
}
bool have(long long x,int y)
{
if(x&(1LL<<y)) return true;
return false;
}
bool cmp(node h,node g)
{
if(h.dis2!=g.dis2) return h.dis2<g.dis2;
for(int i=;i<=min(h.cnt,g.cnt);i++)
if(h.road[i]!=g.road[i]) return h.road[i]<g.road[i];
return h.cnt<g.cnt;
}
void solve()
{
if(dis[a]>2e9)
{
printf("No");
return;
}
if(a==b) k++;
cur.cnt=;
cur.dis2=;
cur.go=1LL<<a;
cur.num=cur.road[]=a;
q2.push(cur);
while(!q2.empty())
{
cur=q2.top(); q2.pop();
if(cur.num==b)
{
sum++;
ans.push_back(cur);
if(sum>k && cur.dis2>ans[k-].dis2) break;
}
for(int i=front2[cur.num];i;i=nxt2[i])
if(!have(cur.go,to2[i]))
{
nt.cnt=cur.cnt+;
nt.dis2=cur.dis2+val2[i];
nt.go=cur.go|(1LL<<to2[i]);
nt.num=to2[i];
for(int j=;j<=cur.cnt;j++) nt.road[j]=cur.road[j];
nt.road[nt.cnt]=to2[i];
q2.push(nt);
}
}
if(ans.size()>=k)
{
sort(ans.begin(),ans.end(),cmp);
printf("%d",a);
for(int i=;i<=ans[k-].cnt;i++) printf("-%d",ans[k-].road[i]);
return;
}
printf("No");
}
int main()
{
read(n); read(m); read(k); read(a); read(b);
int u,v,w;
while(m--)
{
read(u); read(v); read(w);
add(v,u,w);
}
spfa();
solve();
}
T2[ZJOI2007]最大半连通子图
Description
一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意
两点u,v,存在一条u到v的有向路径或者从v到u的有向路径。若G'=(V',E')满足V'?V,E'是E中所有跟V'有关的边,
则称G'是G的一个导出子图。若G'是G的导出子图,且G'半连通,则称G'为G的半连通子图。若G'是G所有半连通子图
中包含节点数最多的,则称G'是G的最大半连通子图。给定一个有向图G,请求出G的最大半连通子图拥有的节点数K
,以及不同的最大半连通子图的数目C。由于C可能比较大,仅要求输出C对X的余数。
Input
第一行包含两个整数N,M,X。N,M分别表示图G的点数与边数,X的意义如上文所述接下来M行,每行两个正整
数a, b,表示一条有向边(a, b)。图中的每个点将编号为1,2,3…N,保证输入中同一个(a,b)不会出现两次。N ≤1
00000, M ≤1000000;对于100%的数据, X ≤10^8
Output
应包含两行,第一行包含一个整数K。第二行包含整数C Mod X.
tarjan缩环,然后拓扑排序求最长链
注意缩环之后重新构图会出现重边,在拓扑排序里计算方案数时会多算
所以拓扑排序时判断一下是否被同一节点重复更新
错因:没有想到重边,存边的数组大小与点混淆
#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 100001
#define M 1000001
using namespace std;
int mod,tot,cnt;
int front[N],nxt[M],to[M],from[M];
int front2[N],nxt2[M],to2[M],ru[N];
int dp[N][],maxn,ans;
int dfn[N],low[N],col[N],siz[N],st[N],top;
bool vis[N];
int last[N];
void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
void add(int u,int v)
{
to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; from[tot]=u;
}
void add2(int u,int v)
{
to2[++tot]=v; nxt2[tot]=front2[u]; front2[u]=tot; ru[v]++;
}
void tarjan(int now)
{
low[now]=dfn[now]=++tot;
st[++top]=now;
vis[now]=true;
for(int i=front[now];i;i=nxt[i])
{
if(!dfn[to[i]])
{
tarjan(to[i]);
low[now]=min(low[now],low[to[i]]);
}
else if(vis[to[i]]) low[now]=min(low[now],dfn[to[i]]);
}
if(low[now]==dfn[now])
{
cnt++;
while(top && st[top]!=now)
{
col[st[top]]=cnt;
vis[st[top]]=false;
top--;
}
col[now]=cnt;
vis[now]=false;
top--;
}
}
void topsort()
{
top=;
for(int i=;i<=cnt;i++)
if(!ru[i])
{
st[++top]=i;
dp[i][]=siz[i];
dp[i][]=;
}
int now;
while(top)
{
now=st[top]; top--;
for(int i=front2[now];i;i=nxt2[i])
{
if(dp[now][]+siz[to2[i]]>dp[to2[i]][])
{
dp[to2[i]][]=dp[now][]+siz[to2[i]];
dp[to2[i]][]=dp[now][];
last[to2[i]]=now;
}
else if(dp[now][]+siz[to2[i]]==dp[to2[i]][])
{
if(last[to2[i]]==now)
{
ru[to2[i]]--;
if(!ru[to2[i]]) st[++top]=to2[i];
continue;
}
last[to2[i]]=now;
dp[to2[i]][]+=dp[now][];
dp[to2[i]][]%=mod;
}
ru[to2[i]]--;
if(!ru[to2[i]]) st[++top]=to2[i];
}
}
}
int main()
{
int n,m;
read(n); read(m); read(mod);
int u,v;
for(int i=;i<=m;i++)
{
read(u); read(v);
add(u,v);
}
tot=;
for(int i=;i<=n;i++)
if(!dfn[i]) tarjan(i);
for(int i=;i<=n;i++) siz[col[i]]++;
tot=;
for(int i=;i<=m;i++)
if(col[from[i]]!=col[to[i]]) add2(col[from[i]],col[to[i]]);
topsort();
for(int i=;i<=cnt;i++) maxn=max(maxn,dp[i][]);
for(int i=;i<=cnt;i++)
if(maxn==dp[i][]) ans+=dp[i][],ans%=mod;
printf("%d\n%d",maxn,ans);
}
?
T3[AHOI2006]上学路线route
Description
Input
Output
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#define N 501
#define M 200001
using namespace std;
int n,m;
int dis[N][N];
int e[M][];
int src,decc;
int tot=,front2[N],to2[M<<],nxt2[M<<],cap[M<<],lev[N],cur[N];
bool vis[N];
queue<int>q;
void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
}
void add2(int u,int v,int w)
{
to2[++tot]=v; nxt2[tot]=front2[u]; front2[u]=tot; cap[tot]=w;
to2[++tot]=u; nxt2[tot]=front2[v]; front2[v]=tot; cap[tot]=;
}
void build()
{
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(k!=i && i!=j && k!=j)
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
int minn=dis[][n];
printf("%d\n",minn);
for(int i=;i<=m;i++)
{
if(dis[][e[i][]]+e[i][]+dis[e[i][]][n]==minn)
add2(e[i][],e[i][],e[i][]);
if(dis[][e[i][]]+e[i][]+dis[e[i][]][n]==minn)
add2(e[i][],e[i][],e[i][]);
} }
bool spfa2()
{
for(int i=;i<=n;i++) cur[i]=front2[i],lev[i]=-;
while(!q.empty()) q.pop();
lev[]=; q.push();
int now;
while(!q.empty())
{
now=q.front(); q.pop();
for(int i=front2[now];i;i=nxt2[i])
if(lev[to2[i]]==- && cap[i]>)
{
lev[to2[i]]=lev[now]+;
if(to2[i]==n) return true;
q.push(to2[i]);
}
}
return false;
}
int dinic(int now,int flow)
{
if(now==n) return flow;
int delta,rest=;
for(int & i=cur[now];i;i=nxt2[i])
if(lev[to2[i]]>lev[now] && cap[i]>)
{
delta=dinic(to2[i],min(cap[i],flow-rest));
if(delta)
{
cap[i]-=delta; cap[i^]+=delta;
rest+=delta; if(rest==flow) break;
}
}
if(rest!=flow) lev[now]=-;
return rest;
}
int main()
{
read(n); read(m);
int u,v,t,c;
memset(dis,,sizeof(dis));
for(int i=;i<=n;i++) dis[i][i]=;
for(int i=;i<=m;i++)
{
read(u); read(v); read(t); read(c);
e[i][]=u; e[i][]=v; e[i][]=t; e[i][]=c;
dis[u][v]=dis[v][u]=min(dis[u][v],t);
}
build();
int ans=;
while(spfa2())
ans+=dinic(,2e9);
printf("%d",ans);
}
NOIP模拟2的更多相关文章
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程
数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...
- 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...
- 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...
- 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1
题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...
- CH Round #58 - OrzCC杯noip模拟赛day2
A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...
- CH Round #52 - Thinking Bear #1 (NOIP模拟赛)
A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...
- CH Round #49 - Streaming #4 (NOIP模拟赛Day2)
A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...
随机推荐
- Scrum立会报告+燃尽图(十月十四日总第五次):前期宣传工作进行中
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2195 Scrum立会master:段晓睿 一.小组介绍 组长:付佳 组员 ...
- 王者荣耀交流协会——第7次Scrum会议
照片由刘耀泽同学拍摄 ,王露芝同学(外援)没有参加本次会议. 要求2 : 时间跨度:2017年10月19日 15:05 - 15:20 共计15分钟 要求3 : 地点:计算机楼107教室 要求4 : ...
- SDN前瞻 传统网络的缺陷
引言 在网络发展速度如此之快的今天,传统网络的架构充满了危机,主要有这四个问题: 传统网络部署管理困难. 分布式架构瓶颈出现. 流量控制难真正实现. 设备不可编程. 现在的网络厂商 种类繁多的网络厂商 ...
- s2sh乱码一个小处理(新手按流程走)
解决乱码几小点: 1.配置过滤器,可以选择自己写,既然你用的SSH框架就更简单了,直接用Spring的过滤器,web.xml里配置一下即可. 2.Jsp页面设置编码,所有地方都要相同,我习惯用GBK ...
- IT小小鸟阅读笔记
人生就像是一艘漂泊的船,你努力滑行了就会找到成功的彼岸,否则就漂泊一生.在这个物欲横流的时代有太多的诱惑使我们静不下心来,但是我们应该时时刻刻警醒自己要做一些对自己成长有意义的事,程序员虽然幸苦但是作 ...
- DataTable转List<T>集合
#region DataTable转List集合 +static IList<T> DataTableToList<T>(DataTable dt) where T : cla ...
- lintcode-24-LFU缓存
24-LFU缓存 LFU是一个著名的缓存算法 实现LFU中的set 和 get 样例 capacity = 3 set(2,2) set(1,1) get(2) >> 2 get(1) & ...
- 【第一周】PSP
日期 C类别 C内容 S开始时间 E结束时间 I间隔(单位:分钟) T净时间(单位:分钟) 9月2日 编程 词频统计 7:35 9:35 10 110 9月3日 读书 构建之法 8:00 9:00 5 ...
- selenium 概念及练习 !
1.selenium中如何判断元素是否存在? 2.selenium中hidden或者是display = none的元素是否可以定位到? 3.selenium中如何保证操作元素的成功率?也就是说如何保 ...
- PHP qrcode 生成二维码
<?php /* 下载地址 : https://sourceforge.net/projects/phpqrcode/ 这里下载的文件名为 phpqrcode-2010100721_1.1.4 ...