https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=328
还是一如既往的菜,过了4题:A,C,D,I
A题:在两点之间找一条路,是的最长的边最短,那么所有的边一定在最小生成树上
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<cstring>
using namespace std;
#define MAXN 3005
#define inf 1000000000
int n;
int mat[3005][3005];
int pre[3005];
int query[3005];
int prim(){
int mini[MAXN],ret=0;
int v[MAXN],i,j,k;
for (i=0;i<n;i++)
mini[i]=inf,v[i]=0,pre[i]=-1;
for (mini[j=0]=0;j<n;j++){
for (k=-1,i=0;i<n;i++)
if (!v[i]&&(k==-1||mini[i]<mini[k]))
k=i;
for (v[k]=1,ret+=mini[k],i=0;i<n;i++)
if (!v[i]&&mat[k][i]<mini[i])
mini[i]=mat[pre[i]=k][i];
}
return ret;
}
int main()
{
int T,t1,m,i,j,x,y,l,Q;
scanf("%d",&T);
for(t1=1;t1<=T;t1++)
{
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
mat[i][j]=1e6+5;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&l);
if(l<mat[x-1][y-1])mat[x-1][y-1]=l;
if(l<mat[y-1][x-1])mat[y-1][x-1]=l;
}
prim();
printf("Case %d\n",t1);
/*for(i=0;i<n;i++)
printf("%d ",pre[i]);
printf("\n");*/
scanf("%d",&Q);
while(Q--)
{
memset(query,0,sizeof(query));
scanf("%d%d",&x,&y);
x--;
y--;
if(x==y)
{
printf("0\n");
continue;
}
query[x]=max(1,query[x]);
while(pre[x]!=-1)
{
query[pre[x]]=max(query[x],mat[x][pre[x]]);
x=pre[x];
//printf("%d %d %d\n",x,pre[x],mat[x][pre[x]]);
}
if(query[y]!=0)
{
printf("%d\n",query[y]);
continue;
}
while(pre[y]!=-1)
{
if(query[pre[y]]!=0)
{
printf("%d\n",max(query[pre[y]],max(query[y],mat[y][pre[y]])));
break;
}
query[pre[y]]=max(query[y],mat[y][pre[y]]);
y=pre[y];
}
if(pre[y]==-1)printf("%d\n",query[y]);
}
printf("\n");
}
return 0;
}
C题:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxx = 105;
struct kuai
{
double x,y;
int tot;
}k[15][15];
int n;
int main()
{
long long cnt = 0;
while(~scanf("%d",&n) && n)
{
cnt = 0;
double nx,ny;
double ans = 0;
memset(k,0,sizeof(k));
for(int i = 0; i < n; i++)
{
scanf("%lf%lf",&nx,&ny);
int x = nx,y = ny;
k[x][y].x += nx;
k[x][y].y += ny;
k[x][y].tot++;
}
for(int i = 0; i < 10; i++)
{
for(int j = 0; j < 10; j++)
{
double nx = k[i][j].x;
double ny = k[i][j].y;
int tot = k[i][j].tot;
if(tot)
for(int i1 = i+1; i1 < 10; i1++)
{
for(int j1 = j+1; j1 < 10; j1++)
{
int tot1 = k[i1][j1].tot;
if(tot1)
{
double nx1 = k[i1][j1].x;
double ny1 = k[i1][j1].y;
ans += nx1 * tot - nx * tot1;
ans += ny1 * tot - ny * tot1;
cnt += 1ll* tot1 * tot;
}
}
}
}
}
ans /= cnt;
printf("%.8lf\n",ans);
}
return 0;
}
D题:Floyd算法求两两最短距离,然后预处理概率,通过递推算出概率即可
#include <bits/stdc++.h>
using namespace std;
#define ll long long
char s[105][105];
int a[105][105];
double e[50];
double p[105][3005];
int t,n,r,q;
int main()
{
scanf("%d",&t);
int step=0;
while (t--)
{
step++;
memset(e,0,sizeof(e));
memset(p,0,sizeof(p));
scanf("%d%d",&n,&r);
for (int i=0;i<n;i++)
{
scanf("%s",s[i]);
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
{
if (s[i-1][j-1]=='Y') a[i][j]=1;
else a[i][j]=10000;
}
}
for (int k=1;k<=n;k++)
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
for (int i=1;i<=r;i++)
{
e[i]=1.0/r;
p[1][i]=1.0/r;
}
for (int i=1;i<n;i++)
{
for (int j=i;j<=i*r;j++)
{
for (int k=1;k<=r;k++)
{
p[i+1][j+k]+=p[i][j]*e[k];
}
}
}
printf("Case %d\n",step);
scanf("%d",&q);
while (q--)
{
int x,y,m;
scanf("%d%d%d",&x,&y,&m);
int len=a[x][y];
if (m>=len*r) printf("1.000000\n");
else
{
double ans=0;
for (int i=len;i<=m;i++)
{
ans+=p[len][i];
}
printf("%.6f\n",ans);
}
}
printf("\n");
}
return 0;
}
I题:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int t,n;
ll x[1005],y[1005];
int main()
{
scanf("%d",&t);
while (t--)
{
memset(x,0,sizeof(x));
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
for (int j=1;j<=9;j++)
{
ll c;
scanf("%lld",&c);
x[i]+=c;
}
scanf("%lld",&y[i]);
}
ll m=1;
int can=1;
int can2=0;
ll g;
for (int i=1;i<=n;i++)
{
if (x[i]<y[i])
{
can=0;
break;
}
if (x[i]==y[i]) m=max(m,x[i]);
else if (x[i]>y[i])
{
if (can2==0) g=x[i]-y[i];
else g=__gcd(g,x[i]-y[i]);
m=max(m,y[i]);
can2=1;
}
}
if (can==1 && can2==1)
{
if (g>m) printf("%lld\n",g);
else printf("impossible\n");
}
else printf("impossible\n");
}
return 0;
}