第一题 60
第二题 100
第三题 50
第四题 100
所以只贴AC代码咯~
**
T2
**
题目描述 Description
**
博艾市将要举行一场汽车拉力比赛。
赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间。
其中一些单元格被定义为路标。组织者希望给整个路线指定一个难度系数D,这样参赛选手从任一路标到达别的路标所经过的路径上相邻单元格的海拔高度差不会大于D。也就是说这个难度系数D指的是保证所有路标相互可达的最小值。任一单元格和其东西南北四个方向上的单元格都是相邻的。
**
输入输出格式 Input/output
**
输入格式:
第一行两个整数M和N。第2行到第M+1行,每行N个整数描述海拔高度。第2+M行到第1+2M
行,每行N个整数,每个数非0即1,1表示该单元格是一个路标。
输出格式:
一个整数,即赛道的难度系数D。
**
输入输出样例 Sample input/output
**
**
题解
**
最小生成树,rank维护当前集合里有没有目标点,合并的时候判断一下就可以了(他们的代码大部分都是DP啊,不知道怎么想的)
**
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=510*510;
struct data{int u,v,w;}e[maxn*2];
int par[maxn],rank[maxn],ma[510][510],cnt,n,m,ans;
bool map[510][510];
void ins(int u,int v,int w){cnt++;e[cnt].v=v;e[cnt].u=u;e[cnt].w=w;}
void ini()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
par[(i-1)*m+j]=(i-1)*m+j;
rank[(i-1)*m+j]=map[i][j];
}
}
}
int find(int x){return x==par[x]?x:par[x]=find(par[x]);}
bool unite(int x,int y){x=find(x);y=find(y);par[y]=x;if(rank[x]&&rank[y])return true;rank[x]+=rank[y];return false;}
bool same(int x,int y){return find(x)==find(y);}
inline bool cmp(data a,data b){return a.w<b.w;}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&ma[i][j]);
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)scanf("%d",&map[i][j]);
ini();
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(i==n&&j==m)continue;
if(i!=n)ins((i-1)*m+j,i*m+j,abs(ma[i][j]-ma[i+1][j]));
if(j!=m)ins((i-1)*m+j,(i-1)*m+j+1,abs(ma[i][j]-ma[i][j+1]));
}
int ans=0;
sort(e+1,e+1+cnt,cmp);
for(int i=1;i<=cnt;i++)
{
int u=e[i].u,v=e[i].v,w=e[i].w;
if(same(u,v))continue;
if(unite(u,v))ans=w;
}
printf("%d",ans);
return 0;
}
**
T4
**
tarjan缩一下点,然后跑spfa,然后就没有然后了……
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <iostream>
using namespace std;
const int maxn=80010,maxm=200010;
struct data{int to,next,w;double p;}e[maxm];
int head[maxn],h[maxn],cnt,n,m,S,dfn[maxn],low[maxn],time,belong[maxn],q[maxn],top,scc;
bool inq[maxn],del[maxn];
long dis[maxn],ans,val[maxn];
void ins(int u,int v,int w,double p){cnt++;e[cnt].p=p;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;e[cnt].w=w;}
struct edge{int to,next,w;}ed[maxm];
void insert(int u,int v,int w){cnt++;ed[cnt].to=v;ed[cnt].next=h[u];h[u]=cnt;ed[cnt].w=w;}
void tarjan(int t)
{
int now=top;
q[++top]=t;
dfn[t]=low[t]=++time;
inq[t]=1;
for(int i=head[t];i;i=e[i].next)
if(!dfn[e[i].to])tarjan(e[i].to),low[t]=min(low[t],low[e[i].to]);
else if(inq[e[i].to])low[t]=min(low[t],dfn[e[i].to]);
if(dfn[t]==low[t])
{
scc++;
del[scc]=1;
while(now!=top)
{
belong[q[top]]=scc;
inq[q[top]]=0;
top--;
}
}
}
void build()
{
cnt=0;
for(int t=1;t<=n;t++)
for(int i=head[t];i;i=e[i].next)
if(belong[t]!=belong[e[i].to])
insert(belong[t],belong[e[i].to],e[i].w);
else
{
int sum=e[i].w;
while(sum)
{
val[belong[t]]+=sum;
sum=(int)(sum*e[i].p);
}
}
}
void spfa(){
memset(inq,0,sizeof(inq));
queue<int> q;
q.push(S);
dis[S]=val[S];
inq[S]=1;
while(!q.empty())
{
int u=q.front();q.pop();
for(int i=h[u];i;i=ed[i].next)
if(dis[ed[i].to]<dis[u]+ed[i].w+val[e[i].to])
{
dis[ed[i].to]=dis[u]+ed[i].w+val[ed[i].to];
if(!inq[ed[i].to])
{
inq[ed[i].to]=1;
q.push(ed[i].to);
}
}
inq[u]=0;
}
for(int i=1;i<=scc;i++)ans=max(ans,dis[i]);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int u,v,w;double f;
scanf("%d%d%d%lf",&u,&v,&w,&f);
ins(u,v,w,f);
}
for(int i=1;i<=n;i++)if(!dfn[i])tarjan(i);
build();
scanf("%d",&S);
S=belong[S];
memset(inq,0,sizeof(inq));
spfa();
cout<<ans;
return 0;
}
不要直接复制代码哟~因为会CE的~~希望你们不要和我一样声明time的变量……(cry-ing)