Day 1:
联合权值:
= =好嘛 我承认这道题我也不造什么算法。。就跟着思路做呗
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=200005;
const int mod=10007;
struct edge
{
int to,next;
}e[maxn*2];
typedef long long ll;
int n;
int u,v;
int k=0;
ll w[maxn];
ll s[maxn];
ll maxx[maxn],sb[maxn];
ll ans1,ans2;
ll head[maxn];
void init()//文件操作
{
freopen("link.in","r",stdin);
freopen("link.out","w",stdout);
}
void add(int u,int v)//建边
{
k++;
e[k].to=v;
e[k].next=head[u];
head[u]=k;
}
void work()
{
for(int i=1;i<=n;i++)
{
int p=head[i];
while(p!=0)//>=0
{
int p1=e[p].to;
s[i]+=w[p1];
if(w[p1]>=maxx[i])
{
sb[i]=maxx[i];
maxx[i]=w[p1];
}
else if(w[p1]>sb[i])
{
sb[i]=w[p1];
}
p=e[p].next;
}
ans1=max(ans1,maxx[i]*sb[i]);
}
for(int i=1;i<=n;i++)
{
int p=head[i];
while(p!=0)//>=0
{
int p1=e[p].to;
ans2+=w[p1]*(s[i]-w[p1]);
ans2%=mod;
p=e[p].next;
}
}
}
int main()
{
init();
scanf("%d",&n);
for(int i=1;i<n;i++)
{
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;i++)
{
scanf("%lld",&w[i]);
}
work();
printf("%lld %lld",ans1,ans2);
return 0;
}
/*
5
1 2
2 3
3 4
4 5
1 5 2 3 10
*/
Day 2:
wireless
= =直接枚举一遍就是了。。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=600;
int d;
int n;
int x,y,k;
int w[maxn][maxn];
int hehe=0;
int ans=0;
void init()
{
freopen("wireless.in","r",stdin);
freopen("wireless.out","w",stdout);
}
int point(int x,int y)//以当前点为中心
{
int sum=0;
for(int i=x-d;i<=x+d;i++)
{
for(int j=y-d;j<=y+d;j++)
{
if(i>=0&&j>=0)
{
sum+=w[i][j];
}
}
}
return sum;
}
int main()
{
init();
scanf("%d",&d);
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d %d %d",&x,&y,&k);
w[x][y]=k;
}
for(int i=0;i<=128;i++)
{
for(int j=0;j<=128;j++)
{
int sb=point(i,j);
if(sb>ans)
{
ans=sb;
hehe=1;
}
else if(ans==sb) hehe++;
}
}
printf("%d %d",hehe,ans);
return 0;
}
/*
1
2
4 4 10
6 6 20
*/
Road
最开始的时候建立反向边,然后从终点dfs一遍,将不能到的点筛掉,如果不能到达起点则直接输出-1,然后再建立正向边,用spfa进行最短路查询。
#include<cstdio>//spfa+dfs
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=10005;
const int maxm=200005;
const int inf=0x7f7f7f;
struct edge
{
int to,next;
}e[maxm*2];
int n,m;
int k,head[maxn];
bool visit[maxn];
bool used[maxn];
bool sb[maxn];
int a[maxm],b[maxm];
int queue[maxn];
int dist[maxn];
int s,t;
void add(int u,int v)
{
k++;
e[k].to=v;
e[k].next=head[u];
head[u]=k;
}
void init()
{
freopen("road.in","r",stdin);
freopen("road.out","w",stdout);
}
void dfs(int t)//先反向搜一次,如果一直未访问该点,则表示不与终点联通,直接输出-1
{
if(used[t]) return;
used[t]=true;
int p=head[t];
while(p!=0)
{
int p1=e[p].to;
// printf("p1=%d\n",p1);
if(!used[p1]) dfs(p1);
p=e[p].next;
}
}
void spfa(int s,int t)
{
memset(dist,inf,sizeof(dist));
int qhead=0,tail=1;
dist[s]=0;
sb[s]=true;
queue[tail]=s;
while(qhead<tail)
{
qhead++;
int p=queue[qhead];
sb[p]=false;
int p1=head[p];
while(p1!=0)
{
if(dist[e[p1].to]>dist[p]+1&&visit[e[p1].to])//spfa只走vis=true的点
{
dist[e[p1].to]=dist[p]+1;
if(!sb[e[p1].to])
{
tail++;
queue[tail]=e[p1].to;
sb[e[p1].to]=true;
}
}
p1=e[p1].next;
}
}
printf("%d\n",dist[t]);
}
int main()
{
init();
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d %d",&a[i],&b[i]);
add(b[i],a[i]);
}
scanf("%d %d",&s,&t);
dfs(t);
if(!used[s]) printf("-1\n");//1次筛选
else//重置
{
memset(e,0,sizeof(e));
memset(head,0,sizeof(head));
for(int i=1;i<=m;i++)
{
add(a[i],b[i]);
}
for(int i=1;i<=n;i++)
{
if(used[i]) visit[i]=true;
int p=head[i];
while(p!=0)
{
int p1=e[p].to;
if(!used[p1]) visit[i]=false;
p=e[p].next;
}
}
spfa(s,t);
}
return 0;
}
/*
3 2
1 2
2 1
1 3
6 6
1 2
1 3
2 6
2 5
4 5
3 4
1 5
*/