Day1

T1.小学奥数。。。

代码:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
long long a,b;
int main()
{
scanf("%lld%lld",&a,&b);
long long ans=a*b-a-b;
printf("%lld",ans);
return 0;
}

 T2:大模拟题,没什么好讲的(我还写的特别麻烦,估计最傻逼的代码)

代码:

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define INF 1000
using namespace std;
int T,l;
bool vis[1005],vis1[10005];
char s[10005],ch[105][10];
bool c[10005],e[1005];
int d[1005];
char ssss[1005],sss[10005],ss[105];
int a[1005],b[1005];
int main()
{
scanf("%d",&T);
while (T--){
bool flag=true;
int sum=0; bool zong=true;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
scanf("%d%s",&l,s+1);
int n=strlen(s+1);
if (s[3]=='n') flag=true;
else flag=false;
if (flag){
int ckr=0;
for (int i=1;i<=n;i++){
if (s[i]=='^'){
ckr=i;
break;
}
}
for (int i=ckr+1;i<=n;i++){
if (s[i]>='0'&&s[i]<='9') sum=sum*10+s[i]-'0';
else break;
}
}
else {
int ckr=0;
for (int i=1;i<=n;i++){
if (s[i]=='('){
ckr=i;
break;
}
}
for (int i=ckr+1;i<=n;i++){
if (s[i]>='0'&&s[i]<='9') sum=sum*10+s[i]-'0';
else break;
}
}
if (!flag) sum=0;
for (int i=1;i<=l;i++){
scanf("%s",ss);
if (ss[0]=='F'){
cin>>ch[i][0];
//scanf("%s",ch[i][0]);
scanf("%s%s",sss+1,ssss+1);
if (sss[1]=='n') a[i]=INF;
else {
int n=strlen(sss+1);
for (int j=1;j<=n;j++) a[i]=a[i]*10+sss[j]-'0';
}
if (ssss[1]=='n') b[i]=INF;
else {
int n=strlen(ssss+1);
for (int j=1;j<=n;j++) b[i]=b[i]*10+(ssss[j]-'0');
}
if (a[i]==INF&&b[i]==INF) d[i]=0;
else if (a[i]>b[i]) d[i]=-1;
else if (a[i]==INF&&b[i]<INF) d[i]=-1;
else if (a[i]<INF&&b[i]<INF) d[i]=0;
else if (a[i]<INF&&b[i]==INF) d[i]=1;
c[i]=true;
}
else c[i]=false;
}
memset(vis,false,sizeof(vis));
memset(vis1,false,sizeof(vis1));
int i=1; int j=1; int tot=0; int bianlitot=0;
int Max1=0;
int flag1=0;
while (j<=l){
if (c[j]==true){
if (vis[ch[j][0]-'a']){
if (zong) puts("ERR");
zong=false;
}
vis[ch[j][0]-'a']=true;
if (flag1==0){
if (d[j]==1) tot++,e[j]=true;
else if (d[j]==0) tot=tot,e[j]=true;
else if (d[j]==-1) flag1++,e[j]=false;
}
else{
tot=tot;
e[j]=false;
if (d[j]==-1) flag1++;
}
bianlitot++;
Max1=max(Max1,tot);
}
else {
bianlitot--;
if (bianlitot<0){
if (zong) puts("ERR");
zong=false;
}
for (int k=j;k>=1;k--){
if (c[k]==true&&vis1[k]==false){
vis[ch[k][0]-'a']=false;
vis1[k]=true;
if (e[k]) tot=tot-d[k];
else if (e[k]==false){
tot=tot;
if (d[k]==-1) flag1--;
}
break;
}
}
Max1=max(Max1,tot);
}
j++;
}
if (!zong) continue;
if (bianlitot!=0) puts("ERR");
else{
if (Max1==sum) puts("Yes");
else puts("No");
}
}
return 0;
}

T3.一看k<=50,很显然的状态就有了

我们考虑用dp[i][j]表示到i这个点浪费了的代价为j,这里浪费的代价可以这么理解:就是到i相比于最短路dis[i]来说长了j,也就是说走了dis[i]+j的路

考虑转移dp[i][j]->dp[v][j+dis[i]+e[i].step-dis[v]](当前走得路径+到v的长度和到v的最短路进行比较,就知道了浪费了多少),其中dis[i]表示到i的最短路

注意更新顺序,关于dis排序来更新

另外DP的时候要先枚举差量,一定是差量小的来更新差量大的

这样就有70分了

我们考虑怎么拿满分。

注意到一个套路,就是如果拓扑排序后有点剩余,那么剩下的点一定构成环

然后对于-1的情况就是有一个0环在路径上

我们用拓扑排序判一下就行了

同一个 0 环上任意一个点到1的最短路和到n的最短路都一样

所以当这个点 i 满足 dis1[i]+disn[i]<=dis1[n]+K 时,就可以输出 -1了

代码:

#include<bits/stdc++.h>
#define N 200005
#define M 100005
using namespace std;
int T,n,m,K,Mod,kk,kkk,kkkk,x,y,z;
int head[M],head1[M],Head[N],dis1[M],dis2[N],ru[M],dp[M][55],tmp[M],q[N*100];
struct Edge{int nxt,to,step;}e[N];
struct Edge1{int nxt,to,step;}e1[N];
struct Edge2{int nxt,to;}E[N];
inline void link(int x,int y,int z){e[++kk].nxt=head[x];e[kk].to=y;e[kk].step=z;head[x]=kk;}
inline void link1(int x,int y,int z){e1[++kkk].nxt=head1[x];e1[kkk].to=y;e1[kkk].step=z;head1[x]=kkk;}
inline void Link(int x,int y){E[++kkkk].nxt=Head[x];E[kkkk].to=y;Head[x]=kkkk;}
inline void spfa1(){
memset(dis1,127,sizeof(dis1));dis1[1]=0;
int left1=1;int right1=1;q[1]=1;
while (left1<=right1){
int u=q[left1++];
for (int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if (dis1[v]>dis1[u]+e[i].step){
dis1[v]=dis1[u]+e[i].step;
q[++right1]=v;
}
}
}
}
inline void spfa2(){
memset(dis2,127,sizeof(dis2));dis2[n]=0;
int left1=1;int right1=1;q[1]=n;
while (left1<=right1){
int u=q[left1++];
for (int i=head1[u];i;i=e1[i].nxt){
int v=e1[i].to;
if (dis2[v]>dis2[u]+e1[i].step){
dis2[v]=dis2[u]+e1[i].step;
q[++right1]=v;
}
}
}
}
int id[N];
inline bool cmp(int x,int y){if(dis1[x]==dis1[y])return id[x]<id[y];else return dis1[x]<dis1[y];}
inline void solve(){
memset(dp,0,sizeof(dp));dp[1][0]=1;
for (int i=1;i<=n;i++) tmp[i]=i;
sort(tmp+1,tmp+n+1,cmp);
for (int k=0;k<=K;k++){//注意先枚举差量,一定是差量小的先更新差量大的
for (int i=1;i<=n;i++){
int u=tmp[i];
for (int j=head[u];j;j=e[j].nxt){
int v=e[j].to;
if (k+dis1[u]+e[j].step-dis1[v]>K) continue;
dp[v][k+(dis1[u]+e[j].step-dis1[v])]=1ll*(dp[v][k+(dis1[u]+e[j].step-dis1[v])]+dp[u][k])%Mod;
}
}
}
int ans=0;
for (int i=0;i<=K;i++) ans=(ans+dp[n][i])%Mod;
if (!ans) puts("-1");else printf("%d\n",ans);
}
bool check(){//拓扑排序找环,如果存在一个环,那么这个环中的点都不会加入到拓扑序中,显然不可能会入度为0
int left1=1;int right1=0;//right1=0打成right1=1了
for (int i=1;i<=n;i++) if (!ru[i]) q[++right1]=i,id[i]=n;
while (left1<=right1){
int u=q[left1++];
for (int i=Head[u];i;i=E[i].nxt){
int v=E[i].to;
if (!--ru[v]) q[++right1]=v;
}
}
for (int i=1;i<=right1;i++) id[q[i]]=i;
for (int i=1;i<=n;i++)
if (ru[i]&&dis1[i]+dis2[i]<=dis1[n]+K) return true;//如果i这个环在可能的路上那么就gg
return false;
}
inline void init(){
memset(Head,0,sizeof(Head));kkkk=0;
memset(head,0,sizeof(head));kk=0;
memset(head1,0,sizeof(head1));kkk=0;
memset(ru,0,sizeof(ru));
}
int main(){
scanf("%d",&T);
while (T--){
init();
scanf("%d%d%d%d",&n,&m,&K,&Mod);
for (int i=1;i<=m;i++){
scanf("%d%d%d",&x,&y,&z);
link(x,y,z);link1(y,x,z);
if (!z) Link(x,y),ru[y]++;
}
spfa1();spfa2();
if (check()) puts("-1");
else solve();
}
return 0;
}
/*1
2 2 6 5
1 2 2
2 1 2*/

  

NOIP2017Day1题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. MinerConstanits.java 常量类

    MinerConstanits.java 常量类 package com.iteye.injavawetrust.miner; /** * 常量类 * @author InJavaWeTrust * ...

  2. EBS 可拓展的外部信用风险导入

    DECLARE l_msg_count NUMBER; l_msg_data VARCHAR2(2000); l_return_status VARCHAR2(30); l_cc_hold_comme ...

  3. Helix Streaming Server 简单配置

    双击桌面上新出现的"HelixServer"图标,正常的话应该如图9,不要关闭这个窗口. 双击"HelixServerAdministrator"图标,输入用户 ...

  4. 如何在VS2013中进行Boost单元测试

    对于如何在VS2013中进行Boost单元测试,这方面资料太少.自己也因此走了不少弯路.下文将会阐述一下如何在VS2013中进行Boost单元测试. 在开始Boost单元测试之前,我们需要先安装VS2 ...

  5. mybatis配置开发

    以mysql为例: 一.需要的架包:mybatis.jar和mysql-connector-java.jar 二.一般会有两类配置文件:数据库配置文件和要执行的sql语句 数据库配置文件(配置文件中有 ...

  6. Linux 获得机器的IP和网卡信息

    Linux 获得机器的IP和网卡信息 代码来自于网络, 我改写了, 有美不敢自专, 特分享之.用法很简单,就3个函数. 头文件getmac.h: /** * getmac.h * * 2014-07- ...

  7. CentOS服务器下JavaEE环境搭建指南(远程桌面+JDK+Tomcat+MySQL)

    --------------------------------------------------------------------------------1 系统设置:1.1 远程桌面设置:通过 ...

  8. 关于C语言程序条件编译的简单使用方法

    #include <stdio.h> #include <stdlib.h> #define Mode //如果定义了Mode,那么就执行这个函数 #ifdef Mode vo ...

  9. Access text files using SQL statements by DB Query Analyzer

    Access text files using SQL statements by DB Query Analyzer Ma Gen feng (Guangdong Unitoll Services ...

  10. LeetCode(52)-Remove Linked List Elements

    题目: Remove all elements from a linked list of integers that have value val. Example Given: 1 --> ...