无法言说
#include
#include
#include
using namespace std;
int main()
{
for(;;)
{
system("datamaker.exe > data.in");//启动数据生成器
system("my.exe < data.in > my.out");//启动“正解”和”暴力“
system("std.exe < data.in > std.out");
if(system("fc my.out std.out"))//如果出锅,就停下来
return-1;
}
return 0;
}
或者
#include
#include
#include
using namespace std;
int main()
{
for(;;)
{
system("start datamaker.exe");//启动数据生成器
Sleep(500);//等待数据输出(极限数据输出大约0.5s)
system("start my.exe");//启动“正解”和”暴力“
system("start std.exe");
Sleep(100);//这个时间取决于你写的暴力的最坏时间
if(system("fc my.out std.out"))//如果出锅,就停下来
{
system("pause");
break;
}
}
return 0;
}
注意审题!根据题目决定是否加入重边或自环
#include
int const maxn=111;
int const N=10;
int const M=25;
int const C=10;
std::stringstream str;
int seed;
int n,a[maxn];
int main(int argc,char *argv[])
{
seed=time(NULL);
if(argc)
{
str.clear();
str<>seed;
}
srand(seed);
n=rand()%N+C+1;
printf("%d\n",n);
for(int i=2;i<=n;i++)
{
int x=rand()%i+1;
if(x==i)
x--;
printf("%d %d\n",i,x);
}
return 0;
}
#include
int const maxn=111;
int const N=10;
int const M=25;
int const C=10;
std::stringstream str;
int seed;
int n,a[maxn];
int main(int argc,char *argv[])
{
seed=time(NULL);
if(argc)
{
str.clear();
str<>seed;
}
srand(seed);
n=rand()%N+C+1;
for(int i=1;i<=n;i++)
a[i]=i;
std::random_shuffle(a+1,a+1+n);
for(int i=2;i<=C;i++)
printf("%d %d\n",a[i],a[i-1]);
for(int i=C+1;i<=n;i++)
{
int x=rand()%a[i]+1;
printf("%d %d\n",i,x);
}
return 0;
}
#include
int const maxn=111;
int const N=10;
int const M=25;
int const C=10;
std::stringstream str;
int seed;
int n,a[maxn];
int main(int argc,char *argv[])
{
seed=time(NULL);
if(argc)
{
str.clear();
str<>seed;
}
srand(seed);
n=rand()%N+C;
printf("%d\n",n);
for(int i=1;i
#include
int const maxn=111;
int const N=10;
int const M=25;
int const C=5;
std::stringstream str;
int seed;
int n,a[maxn],vis[maxn];
int cnt1,cnt2;
int main(int argc,char *argv[])
{
seed=time(NULL);
if(argc)
{
str.clear();
str<>seed;
}
srand(seed);
n=rand()%N+2*C;
printf("%d\n",n);
int root1=rand()%n+1;
int root2=rand()%n+1;
if(root1==root2)
root2=(root2+1)%n+1;
printf("%d %d\n",root1,root2);
vis[root1]=vis[root2]=true;
for(int i=1;i<=n;i++)
a[i]=i;
std::random_shuffle(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
if(cnt1==C)
break;
if(vis[a[i]])
continue;
cnt1++;printf("%d %d\n",root1,a[i]);
vis[a[i]]=true;
}
for(int i=1;i<=n;i++)
{
if(cnt2==C)
break;
if(vis[a[i]])
continue;
cnt2++,printf("%d %d\n",root2,a[i]);
vis[a[i]]=true;
}
for(int i=1;i<=n;i++)
{
if(vis[a[i]])
continue;
int x=rand()%a[i]+1;
printf("%d %d\n",a[i],x);
}
return 0;
}
#include
int const maxn=111;
int const N=10;
int const M=25;
int const C=5;
std::stringstream str;
int seed;
int n,a[maxn],vis[maxn];
int cnt1,cnt2;
int main(int argc,char *argv[])
{
seed=time(NULL);
if(argc)
{
str.clear();
str<>seed;
}
srand(seed);
n=rand()%N+3*C;
printf("%d\n",n);
for(int i=1;i<=C;i++)
printf("%d %d\n",i,i+1),vis[i]=true,vis[i+1]=true;
int root1=rand()%n+1;
while(vis[root1])
root1=rand()%n+1;
vis[root1]=true;
int root2=rand()%n+1;
while(vis[root2])
root2=rand()%n+1;
vis[root2]=true;
printf("%d %d\n%d %d\n",root1,1,root2,C+1);
vis[root1]=vis[root2]=true;
for(int i=1;i<=n;i++)
a[i]=i;
std::random_shuffle(a+1,a+1+n);
for(int i=1;i<=n;i++)
{
if(cnt1==C)
break;
if(vis[a[i]])
continue;
cnt1++;printf("%d %d\n",root1,a[i]);
vis[a[i]]=true;
}
for(int i=1;i<=n;i++)
{
if(cnt2==C)
break;
if(vis[a[i]])
continue;
cnt2++,printf("%d %d\n",root2,a[i]);
vis[a[i]]=true;
}
for(int i=1;i<=n;i++)
{
if(vis[a[i]])
continue;
int x=rand()%a[i]+1;
printf("%d %d\n",a[i],x);
}
return 0;
}
//unique(u,v)返回去重(伪)后的地址+1,被删掉的会加到后面,以返回值为首地址
int const maxn=1e5+10;
int a[maxn], t[maxn];
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",a[i]),t[i]=a[i];
sort(t+1,t+n+1);//排序,找相对大小
m=unique(t+1,t+1+n)-t-1;//m为不重复的元素的个数
for(int i=1; i<=n; i++)
a[i]=lower_bound(t+1,t+1+m,a[i])-t;//返回b中第一个大于等于a[i]的位置
int abs(int x){ return (x^(x>>31))-(x>>31);}
double abs(double x){ return x>esp:x?-x;}
void swap(int &a,int &b){a^=b;b^=a;a^=b;}
int pan(int x){return x&1;}
int pan(int x,int y){return !((x^y)>>31);}
struct node
{
int nd,dis;
bool operator<(const node &b)const
{
return dis>b.dis;
}
//从大到小排序
node(int nd=0,int dis=0):
nd(nd),dis(dis){}
};
解决具有严格更新顺序的图论问题
一般结合DP使用(如树形DP)
void topsort(int s)
{
std::queueq;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to;
ind[v]--;
f[v]=f[u]+change;
if(!ind[v])
q.push(v);
}
}
}
把queue改成结构体,跑topsort的时候顺便维护一下深度
prim每次找到集合内到集合外的最短边
这样我们就可以把每个点扩展到的边压成点放进小根堆里堆里
如果u已经在集合内,直接continue
每次取堆顶即可
struct node
{
int id,dis;
bool operator <(const node &b)const
{
return dis>b.dis;
//优先队列默认大根堆
//这里把他重载成小根堆
}
node(int id=0,int dis=0):
id(id).dis(dis){}
};
void prim(int s)
{
std::priority_queueq;
q.push(node(s,0));
cost[s]=0;
while(!q.empty())
{
int u=q.top().id,dis=q.top().dis;
q.pop();
if(set[u])
continue;
ans+=dis;
set[u]=true;
//注意,dijkstra可以不加访问标记,因为dijkstra能保证每个点只入队一次
//prim则不能保证
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to,w=e[i].w;
if(cost[v]>w)
cost[v]=w,q.push(node(v,w));
}
}
printf("%d",ans);
}
int find(int x)
{
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int cmp(RE x,RE y)
{
return x.w
无向图 G G G的一颗瓶颈生成树是这样的一颗生成树,
它最大的边权值在 G G G的所有生成树中是最小的。瓶颈生成树的值为T中最大权值边的权。
最小生成树一定是瓶颈生成树
瓶颈生成树不一定是最小生成树
由于kruskal的性质,第一棵求出的生成树就是瓶颈生成树
最小瓶颈路问题是指在一张无向图中,有多组询问,每组询问提供一个一个点对 ( u , v ) (u,v) (u,v),需要找出从 u u u到 v v v的一条简单路径,使路径上所有边中最大值最小
最小生成树中u到v的路径一定是最小瓶颈路之一
因此我们可以先搞一棵 M S T MST MST,然后问题转化为了求 M S T MST MST中 ( u , v ) (u,v) (u,v)的最大边权
这个用倍增LCA或者树剖都能搞
求出一棵生成树,其所有边的权值之和仅次于最小生成树的权值之和
先求出 M S T MST MST,然后枚举加入不在 M S T MST MST上的边,这样势必会构成环,我们则需要在环上断开一条边回到树形结构
自此问题转化为求 M S T MST MST上 ( u , v ) (u,v) (u,v)两个点之间的最大边权,这显然是个最小瓶颈路问题,解法同上
从包含n个点的空图开始,依次加入m条带权边。每加入一条边输出当前图的最小生成树的权值,不连通输出无解
int main()
{
scanf("%d%d"&n,&m);
for(int u,v,w,i=1;i<=m;i++)
{
scanf("%d%d%d“,&u,&v,&w1);
if(num=n-1)
printf("%d\n",MST);
num++;
}
}
#include
int const maxn=111;
struct Tree
{
int lc,rc,sum,tag;
}a[maxn<<1];
int t=1;
int w[maxn];
void pushup(int u)
{
a[u].sum=a[a[u].lc].sum+a[a[u].rc].sum;
}
void build(int u,int l,int r)
{
if(l==r)
{
a[u].sum=w[l];return;
}
int mid=l+r>>1;
a[u].lc=++t;
build(a[u].lc,l,mid);
a[u].rc=++t;
build(a[u].rc,mid+1,r);
pushup(u);
}
void pushdown(int u,int l,int r)
{
int lc=a[u].lc,rc=a[u].rc,tag=a[u].tag;
int mid=l+r>>1;
a[lc].sum+=tag*(mid-l+1);
a[lc].tag+=tag;
a[rc].sum+=tag*(mid-r);
a[rc].tag+=tag;
a[u].tag=0;
}
void update_plus(int u,int l,int r,int ll,int rr,int dlt)
{
if(l==ll&&r==rr)
{
a[u].sum+=dlt*(l-r+1);
a[u].tag+=dlt;
return;
}
pushdown(u,l,r);
int mid=l+r>>1;
if(rr<=mid)
update_plus(a[u].lc,l,mid,ll,rr,dlt);
else if(ll>mid)
update_plus(a[u].rc,mid+1,r,ll,rr,dlt);
else
update_plus(a[u].lc,l,mid,ll,mid,dlt),update_plus(a[u].rc,mid+1,r,mid+1, rr,dlt);
pushup(u);
}
int query(int u,int l,int r,int ll,int rr)
{
if(l==ll&&r==rr)
return a[u].sum;
pushdown(u,l,r);
int mid=l+r>>1;
return rr<=mid?query(a[u].lc,l,mid,ll,rr):(ll>mid?query(a[u].rc,mid+1,r,ll,rr):query(a[u].lc,l,mid,ll,mid)+query(a[u].rc,mid+1,r,mid+1,rr));
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&w[i]);
build(1,1,n);
for(int op,x,y,z,i=1;i<=m;i++)
{
scanf("%d%d%d",&op,&x,&y);
if(op==1)
{
scanf("%d",&z);
update_plus(1,1,n,x,y,z);
}
else
printf("%d\n",query(1,1,n,x,y));
}
return 0;
}