• 【YbtOJ#20073】钻石守卫


    题目

    题目链接:http://noip.ybtoj.com.cn/problem/20073

    思路

    发现一个连通块内,我们只要确定了一个点的权值,其他点的权值都可以求出。
    所以我们可以设其中一个点权值为 (x),然后根据每条道路连接两个点的点权和等于路径权值可以将每一个点的权值写成若干个 (kx+b) 的形式。
    对于第 (i) 个点的所有方程,都需要满足 (0leq kx+bleq p_i),所以我们可以解出 (x) 的取值范围。
    然后对于同一个点,关于它的所有方程的值都必须一致。所以如果存在两个方程无解,那么整张图无解;如果两个方程有唯一解,那么第一个点的权值也只有唯一解,其他点同理也都只有唯一解;否则肯定是在 (x) 取值范围区间的最小值和最大值取答案最优。
    所以将每一个方程求出并计算答案即可。
    时间复杂度 (O(n+m))

    代码

    本代码由于常数过大只可以得到 (80) pts。实在是卡不动了 /kk。

    //#pragma GCC optimize("Ofast","inline")
    #include <bits/stdc++.h>
    #define mp make_pair
    #define ST first
    #define ND second
    using namespace std;
    typedef long long ll;
    
    const int N=500010,M=6000010;
    int n,m,tot,L,R,p[N],head[N],vis[N],a[N],K[N],B[N];
    ll mxans,mnans,QuantAsk,my_dog;
    bool flag=1;
    vector<pair<int,int> > equ[N];
    
    int read()
    {
    	int d=0; char ch=getchar();
    	while (!isdigit(ch)) ch=getchar();
    	while (isdigit(ch)) d=(d<<3)+(d<<1)+ch-48,ch=getchar();
    	return d;
    }
    
    struct edge
    {
    	int next,to,dis;
    }e[M];
    
    void add(int from,int to,int dis)
    {
    	e[++tot].to=to;
    	e[tot].dis=dis;
    	e[tot].next=head[from];
    	head[from]=tot;
    }
    
    void bfs1(int S)
    {
    	queue<int> q;
    	q.push(S);
    	while (q.size())
    	{
    		int x=q.front(); q.pop();
    		a[++tot]=x;
    		vis[x]=1; 
    		int k=equ[x][0].ST,b=equ[x][0].ND;
    		for (int i=head[x];~i;i=e[i].next)
    		{
    			int v=e[i].to;
    		/*	if (v!=fa)
    			{*/
    				//equ[v].push_back(mp(-k,e[i].dis-b));
    				
    				int k1=equ[x][i].ST,k2=equ[x][i-1].ST;
    				int b1=equ[x][i].ND,b2=equ[x][i-1].ND;
    				if (k1==k2 && b1==b2) continue;
    				if (k1==k2 && b1!=b2) { flag=0; return; }
    		//		if (k1!=k2 && b1==b2) { flag=0; return; }
    				if ((b2-b1)%(k1-k2)) { flag=0; return; }
    				if ((b2-b1)/(k1-k2)<L || (b2-b1)/(k1-k2)>R) { flag=0; return; }
    				L=R=(b2-b1)/(k1-k2);
    				
    				if (!vis[v]) q.push(v),vis[v]=1;
    			//}
    		}
    		for (int i=0;i<equ[x].size();i++)
    			if (equ[x][i].ST==1)
    				L=max(L,-equ[x][i].ND),R=min(R,p[x]-equ[x][i].ND);
    			else
    				L=max(L,equ[x][i].ND-p[x]),R=min(R,equ[x][i].ND);
    	}
    }
    /*
    void dfs1(int x,int fa)
    {
    	vis[x]=1; 
    	int k=equ[x][0].ST,b=equ[x][0].ND;
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if (v!=fa)
    		{
    			equ[v].push_back(mp(-k,e[i].dis-b));
    			if (!vis[v]) dfs1(v,x);
    		}
    	}
    	for (int i=0;i<equ[x].size();i++)
    		if (equ[x][i].ST==1)
    			L=max(L,-equ[x][i].ND),R=min(R,p[x]-equ[x][i].ND);
    		else
    			L=max(L,equ[x][i].ND-p[x]),R=min(R,equ[x][i].ND);
    }
    */
    void bfs2(int S)
    {
    	queue<int> q;
    	q.push(S);
    	while (q.size())
    	{
    		int x=q.front(); q.pop();
    		vis[x]=2;
    		for (int i=1;i<equ[x].size();i++)
    		{
    			int k1=equ[x][i].ST,k2=equ[x][i-1].ST;
    			int b1=equ[x][i].ND,b2=equ[x][i-1].ND;
    			if (k1==k2 && b1==b2) continue;
    			if (k1==k2 && b1!=b2) { flag=0; return; }
    	//		if (k1!=k2 && b1==b2) { flag=0; return; }
    			if ((b2-b1)%(k1-k2)) { flag=0; return; }
    			if ((b2-b1)/(k1-k2)<L || (b2-b1)/(k1-k2)>R) { flag=0; return; }
    			L=R=(b2-b1)/(k1-k2);
    		}
    		for (int i=head[x];~i;i=e[i].next)
    		{
    			int v=e[i].to;
    			if (vis[v]!=2) q.push(v),vis[v]=2;
    			if (!flag) return;
    		}
    	}
    }
    /*
    void dfs2(int x)
    {
    	vis[x]=2;
    	for (int i=1;i<equ[x].size();i++)
    	{
    		int k1=equ[x][i].ST,k2=equ[x][i-1].ST;
    		int b1=equ[x][i].ND,b2=equ[x][i-1].ND;
    		if (k1==k2 && b1==b2) continue;
    		if (k1==k2 && b1!=b2) { flag=0; return; }
    //		if (k1!=k2 && b1==b2) { flag=0; return; }
    		if ((b2-b1)%(k1-k2)) { flag=0; return; }
    		if ((b2-b1)/(k1-k2)<L || (b2-b1)/(k1-k2)>R) { flag=0; return; }
    		L=R=(b2-b1)/(k1-k2);
    	}
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if (vis[v]!=2) dfs2(v);
    		if (!flag) return;
    	}
    }
    */
    
    void bfs3(int S)
    {
    	queue<int> q;
    	q.push(S);
    	while (q.size())
    	{
    		int x=q.front(); q.pop();
    		vis[x]=3;
    		int k=equ[x][0].ST,b=equ[x][0].ND;
    		QuantAsk+=p[x]-(k*L+b); my_dog+=p[x]-(k*R+b);
    		for (int i=head[x];~i;i=e[i].next)
    		{
    			int v=e[i].to;
    			if (vis[v]!=3) q.push(v),vis[v]=3;
    		}
    	}
    }
    /*
    void dfs3(int x)
    {
    	vis[x]=3;
    	int k=equ[x][0].ST,b=equ[x][0].ND;
    	QuantAsk+=p[x]-(k*L+b); my_dog+=p[x]-(k*R+b);
    	for (int i=head[x];~i;i=e[i].next)
    	{
    		int v=e[i].to;
    		if (vis[v]!=3) dfs3(v);
    	}
    }*/
    
    int main()
    {
    	freopen("diamond.in","r",stdin);
    	freopen("diamond.out","w",stdout);
    	memset(head,-1,sizeof(head));
    	n=read(); m=read();
    	for (int i=1;i<=n;i++)
    		p[i]=read();
    	for (int i=1,x,y,z;i<=m;i++)
    	{
    		x=read(); y=read(); z=read();
    		add(x,y,z); add(y,x,z);
    	}
    	for (int i=1;i<=n;i++)
    		if (!vis[i])
    		{
    			L=0; R=1e9; QuantAsk=my_dog=0; tot=0;
    			equ[i].push_back(mp(1,0));
    			//dfs1(i,0); dfs2(i);
    			bfs1(i); /*bfs2(i);*/
    			for (int k=1;k<=tot;k++)
    			{
    				int x=a[k];
    				for (int j=1;j<equ[x].size();j++)
    				{
    					int k1=equ[x][j].ST,k2=equ[x][j-1].ST;
    					int b1=equ[x][j].ND,b2=equ[x][j-1].ND;
    					if (k1==k2 && b1==b2) continue;
    					if (k1==k2 && b1!=b2) { flag=0; break; }
    			//		if (k1!=k2 && b1==b2) { flag=0; break; }
    					if ((b2-b1)%(k1-k2)) { flag=0; break; }
    					if ((b2-b1)/(k1-k2)<L || (b2-b1)/(k1-k2)>R) { flag=0; break; }
    					L=R=(b2-b1)/(k1-k2);
    				}
    			}
    			if (!flag || L>R) return printf("NIE"),0;
    			//dfs3(i);
    			for (int j=1;j<=tot;j++)
    			{
    				int k=equ[a[j]][0].ST,b=equ[a[j]][0].ND;
    				QuantAsk+=p[a[j]]-(k*L+b); my_dog+=p[a[j]]-(k*R+b);
    			}
    			//bfs3(i);
    			mnans+=min(my_dog,QuantAsk);
    			mxans+=max(my_dog,QuantAsk);
    		}
    	printf("%lld %lld",mnans,mxans);
    	return 0;
    }
    
  • 相关阅读:
    django-restframework频率功能、过滤功能等相关内容-87
    django-restframework认证功能等相关内容-86
    视图基类、扩展类、子类及试图集等相关内容-85
    vue框架前后端分离项目之课程接口、页面、前台等相关内容-127
    vue框架前后端分离项目之课程页面前端、课程表分析、编写及数据录入等相关内容-126
    celery的基础使用等相关内容-125
    数据库时间戳排序协议
    单节点部署OpenStack(Queens版本、DevStack)
    变量命名规范及str类型
    程序员职业生涯规划
  • 原文地址:https://www.cnblogs.com/stoorz/p/13879787.html
Copyright © 2020-2023  润新知