期望得分: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

可可和卡卡家住合肥市的东郊,每天上学他们都要转车多次才能到达市区西端的学校。直到有一天他们两人参加了学校的信息学奥林匹克竞赛小组才发现每天上学的乘车路线不一定是最优的。 可可:“很可能我们在上学的路途上浪费了大量的时间,让我们写一个程序来计算上学需要的最少时间吧!” 合肥市一共设有N个公交车站,不妨将它们编号为1…N的自然数,并认为可可和卡卡家住在1号汽车站附近,而他们学校在N号汽车站。市内有M条直达汽车路线,执行第i条路线的公交车往返于站点pi和qi之间,从起点到终点需要花费的时间为ti。(1<=i<=M, 1<=pi, qi<=N) 两个人坐在电脑前,根据上面的信息很快就编程算出了最优的乘车方案。然而可可忽然有了一个鬼点子,他想趁卡卡不备,在卡卡的输入数据中删去一些路线,从而让卡卡的程序得出的答案大于实际的最短时间。而对于每一条路线i事实上都有一个代价ci:删去路线的ci越大卡卡就越容易发现这个玩笑,可可想知道什么样的删除方案可以达到他的目的而让被删除的公交车路线ci之和最小。 [任务] 编写一个程序:  从输入文件中读取合肥市公交路线的信息;  计算出实际上可可和卡卡上学需要花费的最少时间;  帮助可可设计一个方案,删除输入信息中的一些公交路线,使得删除后从家到学校需要的最少时间变大,而被删除路线的ci和最小;向输出文件输出答案。

Input

输入文件中第一行有两个正整数N和M,分别表示合肥市公交车站和公交汽车路线的个数。以下M行,每行(第i行,总第(i+1)行)用四个正整数描述第i条路线:pi, qi, ti, ci;具体含义见上文描述。

Output

输出文件最多有两行。 第一行中仅有一个整数,表示从可可和卡卡家到学校需要的最短时间。 第二行输出一个整数C,表示Ci之和
 
思路:找出所有的最短路,重新建图,跑最小割
错因:
确定这条边在最短路上:
正确方法:dis[s,u]+w+dis[v,t]=dis[s,t]
错误方法:从t开始枚举,dis[1,u]+w=dis[1,v],只是计算了1到某个点的最短路
#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的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  3. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  6. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  8. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  9. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

  10. CH Round #49 - Streaming #4 (NOIP模拟赛Day2)

    A.二叉树的的根 题目:http://www.contesthunter.org/contest/CH%20Round%20%2349%20-%20Streaming%20%234%20(NOIP 模 ...

随机推荐

  1. 5月5号周二课堂练习:简评cnblogs.com的用户体验

    一.用户类型 在博客园上写博客,提问题,浏览感兴趣的博客帖子的活跃用户. 二.对cnblogs的期望 在博客园上写博客更流畅,制作手机版的APP可以随时随地在线浏览大牛们写的博客,提出的问题能更好的更 ...

  2. [转]Android试验:如果View的ID相同会出现什么效果?

    1.实验:通过布局编辑器强行指定两个button id相同,然后在代码中通过findViewById()获得句柄后修改其文本.  实验结果:只有一个button的文本变化了,另一个不受影响.  2.实 ...

  3. 周总结<1>

    由于都不清楚周总结的格式,所以就没有写了.不过,上次听了老师的课,觉得应该要好好写写了,至少今后可以明白自己有做过什么事情,至少不会觉得自己在各个方面没有收获.不过,可能没有按照格式来写.希望老师体谅 ...

  4. Strust2: 工作流程

    以下为Struts2的体系结构图: Struts2框架处理用户请求,大体分为以下几个过程: (1)用户发出一个HttpServletRequest请求 (2)请求经过一系列过滤器,最后达到Filter ...

  5. 如何在windows下Apache环境开启htaccess伪静态功能

     以下文章来自于网络,只做学习用 很多国人习惯用windows服务器或者在windows系统下调试PHP程序,在调试货使用的时候就遇到开启伪静态的各种问题,今天在网络上搜集了一些开启伪静态需要注意 ...

  6. C#获取当前路径的方法如下

    1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName -获取模块的完整路径. 2. System.Environm ...

  7. spring 整合 struts2 + Hibernate application配置文件(基于注解)

    下面是 application.xml 文件. <?xml version="1.0" encoding="UTF-8"?> <beans x ...

  8. JSP 问题总结

    <input type="button" value="返回" onclick="javascript:window.location.href ...

  9. IIS部署时未能加载程序集"System.Web.Http.WebHost"解决方法

    问题如下 服务器没有安装MVC,下载以下dll覆盖到bin目录下,即可免安装运行程序. 下载地址:https://pan.baidu.com/s/1mhCo5mS

  10. 第142天:Size Marks下载安装和使用方法

    Size Marks下载安装使用方法 一.下载安装 1.下载Size marks:链接: https://pan.baidu.com/s/1breyMf1 密码: fjsn 2. 复制 Size Ma ...