补坑简单图论题

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

凯丽王国有 nnn 座城市,每个城市都有一个能量值 viv_ivi​,mmm 条单向道路连接着这些城市,但这些路不会构成环,即从任意一个城市出发,都无法回到这个城市

而大马猴和机智羊要组队参加的下一个项目就是能量收集赛。能量收集赛的规则是:每位参赛者拿着一个能量值为 000 的水晶球,从他所在的城市出发,每经过一个他从未到达的城市,就可以收集这个城市的能量值并加入自己的能量球中,直到走到无法再走为止。

所以每个参赛者都会收集尽可能多的能量。大马猴和机智羊都很聪明,他们在研究了地图之后,各自都能找到能量最多的路线。

然而当他们完成比赛之后,他们才被告知,他们是作为小组参赛,必须交上去两个能量值一样的能量球才行。他们研究发现,只要花费 x×(x+1)x\times(x+1)x×(x+1) 的钱,就能将能量球的能量值从 xxx 提升为 x+1x+1x+1。

鲨鱼博士想知道,如果大马猴一开始在城市 qqq,机智羊一开始在城市 ppp,那么:

  • 大马猴和机智羊的成绩(刚完成比赛时)分别是多少?

  • 为了使得他们的成绩有效,他们需要花费多少钱?

输入描述:

 
 

第一行包含 333 个正整数 nnn,mmm,ttt,分别表示城市的数量,单向道路的数量,询问次数。

第二行 nnn 个正整数 viv_ivi​ ,依次表示每个城市的能量值。

接下来 mmm 行,每行两个正整数 xix_ixi​ ,yi y_iyi​ ,表示存在一条单向道路,可以从城市 xix_ixi​ 出发到达城市 yiy_iyi​ 。

接下来 ttt 行,每行两个正整数 qqq , ppp ,表示大马猴和机智羊一开始所在的城市。

输出描述:

 
 

对于每次询问,输出一行,三个整数,以空格作为分割,分别表示大马猴和机智羊刚完成比赛时的成绩,以及想要使得成绩有效,需要花费的钱

由于答案太大,请对 109+710^9+7109+7 取模。

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

输入

复制5 6 1 1 1 1 1 1 1 2 1 3 2 5 3 4 3 5 4 5 1 2

5 6 1
1 1 1 1 1
1 2
1 3
2 5
3 4
3 5
4 5
1 2

输出

复制4 2 18

4 2 18

说明

 
 

大马猴的路线为 1⇒3⇒4⇒51\Rightarrow3\Rightarrow4\Rightarrow51⇒3⇒4⇒5,收集到的能量为 1+1+1+1=41+1+1+1=41+1+1+1=4;

机智羊的路线为 2⇒52\Rightarrow52⇒5,收集到的能量为 1+1=21+1=21+1=2;

想要让两个人的能量值一样,先将机智羊的能量从 222 变为 333,即花费 2×32\times32×3 的钱;再从 333 变为 444,即花费 3×43\times43×4 的钱,共 2×3+3×4=182\times 3+3\times4=182×3+3×4=18。

示例2

输入

复制8 9 2 2 2 1 2 1 3 5 2 1 2 1 3 2 4 3 4 4 5 4 7 5 8 6 3 6 4 1 6 5 5

8 9 2
2 2 1 2 1 3 5 2
1 2
1 3
2 4
3 4
4 5
4 7
5 8
6 3
6 4
1 6
5 5

输出

复制11 11 0 3 3 0

11 11 0
3 3 0

说明

 
 

对于第一次询问:

大马猴的路线为 1⇒2⇒4⇒71\Rightarrow2\Rightarrow4\Rightarrow71⇒2⇒4⇒7,收集到的能量为 2+2+2+5=112+2+2+5=112+2+2+5=11;

机智羊的路线为 6⇒3⇒4⇒76\Rightarrow3\Rightarrow4\Rightarrow76⇒3⇒4⇒7,收集到的能量为 3+1+2+5=113+1+2+5=113+1+2+5=11;

两个人的能量值一样,成绩有效。

对于第二次询问:

两个人的路线都为 5⇒85\Rightarrow85⇒8,收集到的能量都为 1+2=31+2=31+2=3,显然成绩有效。

备注:

 
 

#include<bits/stdc++.h>
typedef long long ll;
typedef double db;
using namespace std;
const int mod=1e9+7;
ll n,m,t;
const int N=5e4+5;
const int M=5e5+5;
vector<ll>G[M];
ll f[M];
ll a[N];
ll dfs(ll x,ll fa)
{
    if(f[x])
        return f[x];
    for(int i=0; i<G[x].size(); i++)
    {
        if(G[x][i]!=fa)
            f[x]=max(f[x],dfs(G[x][i],x));
    }
    f[x]+=a[x];
    return f[x];
}
int main()
{
    cin>>n>>m>>t;
    for(int i=1; i<=n; i++)
    {
        cin>>a[i];
    }
    for(int i=1; i<=m; i++)
    {
        ll x,y;
        cin>>x>>y;
        G[x].push_back(y);
    }
    for(int i=1;i<=t;i++)
    {
        ll p,q;
        cin>>p>>q;
        p=dfs(p,0);
        q=dfs(q,0);
        cout<<p<<" "<<q<<" ";
        if(p>q)
            swap(p,q);
        p--;
        q--;
        ll p1=p+1;
        ll p2=p+2;
        ll q1=q+1;
        ll q2=q+2;
        if(p%3==0)p/=3;
        else if(p1%3==0)p1/=3;
        else p2/=3;
        if(q%3==0)q/=3;
        else if(q1%3==0)q1/=3;
        else q2/=3;
        ll sum=(q2%mod*q1%mod*q%mod-p2%mod*p1%mod*p%mod+mod)%mod;
        cout<<sum<<endl;
    }


    return 0;
}

 

#include<bits/stdc++.h>
using namespace std;
const int N = 200010;

int n, m, mod = 1e9+7;
long long dp[N], cnt = 0, t, a[N], ans;

vector<int> G[N];

long long  quick(long long a,long long b,long long p){
	long long ans=1;
	while(b){
		if(b&1) ans=(long long)ans*a%p;
		a=(long long)a*a%p;
		b>>=1;
	}
	return ans;
}
long long Dfs(int x){
	if(dp[x] != -1) return dp[x];
	dp[x] = a[x];
	for (int j = 0; j < G[x].size(); j++){
//		if(In[G[x][j]] > 1 && out[x] > 1){
			dp[x] = max(dp[x], Dfs(G[x][j]) + a[x]);
//		}
	}
	return dp[x];
}
int main(){
	scanf("%d%d%d", &n, &m, &t);
	for (int i = 1; i <= n; i++){
		scanf("%lld", &a[i]);
	}
	memset(dp, -1, sizeof(dp));
	for (int i = 1; i <= m; i++){
		int x, y;
		scanf("%d%d", &x, &y);
		G[x].push_back(y);
	}	
	for (int i = 1; i <= n; i++){
		ans = max(ans, Dfs(i));
	}
	while(t--){
		int q, p;
		scanf("%d%d", &q, &p);
		printf("%lld %lld ", dp[q], dp[p]);
		long long minn = min(dp[q], dp[p]);
		long long maxn = max(dp[q], dp[p]);
		long long ans1 = ((maxn-1) %mod*(maxn)%mod)%mod *(maxn +1)%mod *quick(3,mod-2,mod)%mod;
		long long ans2 = ((minn-1) %mod*(minn)%mod)%mod *(minn +1)%mod *quick(3,mod-2,mod)%mod;
		if(ans1 < ans2) ans1 += mod;
		long long ans = ans1 - ans2;
//		ans = ans * quick(3,mod-2,mod);
		printf("%lld\n", ans);
	}
//	int ans = 0;
//	cout << ans << endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define N 500001
#define mod 1000000007
int a[N];
vector<int>ne[N];
int ans[N],v[N];
int dfs(int x){
    if(v[x]){
        return ans[x];
    }
    v[x]=1;
    int maxx=0;
    vector<int>ne1=ne[x];
    for(int i=0;i<ne1.size();i++){
        maxx=max(maxx,dfs(ne1[i]));
    }
    return ans[x]=maxx+a[x];
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
	int n,m,t;
    cin>>n>>m>>t;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=1;i<=m;i++){
        int x,y;
        cin>>x>>y;
        ne[x].push_back(y);
    }
    for(int i=1;i<=n;i++){
    	if(!v[i]){
    		dfs(i);
		}
	}
    while(t--){
        int p,q;
        cin>>p>>q;
        int x=ans[p],y=ans[q];
        cout<<x<<" "<<y<<" ";
        if(x>y){
        	int t=x;
			x=y;
			y=t; 
		}
		x--;y--;
		int sum=0;
        int y1=y+1,y2=y+2,x1=x+1,x2=x+2;
        if(y%3==0)y/=3;
        else if(y1%3==0)y1/=3;
        else y2/=3;
        if(x%3==0)x/=3;
        else if(x1%3==0)x1/=3;
        else x2/=3;
		sum=y%mod*y1%mod*y2%mod+mod-x%mod*x1%mod*x2%mod;
		cout<<sum%mod<<"\n";
    }
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值