[POI2012]FES-Festival
题意
对于一些数字,有两种限制;1:a+1=b;2:a<=b;
求这些数字最多有多少不同数值。
对于100%的数字n<=600,限制<=1e5
题解
可以得到将限制转化:1:b<=a+1<=b-->b<=a+1,a<=b-1
2:a<=b+0
那么可以建出边,跑最短路;
找负环时,如果用bfs版spfa会发现出发点可能和负环不连通。
于是先tarjan找出联通块,建虚拟源点连向每个联通块,再跑spfa。
注意到联通块之间只用边权为0的边连接,这些边是由第二个限制产生,即a<=b,但这并不确定绝对大小,所以对于b所在联通块可以无限增大值,这样就可以使得两者的值无交集,那么就可以使得有更多取值。
对于同一联通块,里面的边只有1或-1,所以里面的取值是连续的,所以取值数量就是最大的差值+1.
这里主要想记一种floyed求负环;
秩序在跑出floyed后判断f[i][i]是否为0,设初值为0.
在floyed时,判断是否在同一联通块和是否有边可以做到强力剪枝,快到飞起。

#include<bits/stdc++.h> using namespace std; const int maxn=605; const int maxm=100005; int n,m1,m2; int mx[maxn],ans; int cur,cnt,dfn[maxn],low[maxn]; int top,sta[maxn],res[maxn]; bool tag[maxn]; int dis[maxn][maxn]; vector<pair<int,int> >e[maxn]; void tarjan(int u){ low[u]=dfn[u]=++cur; sta[++top]=u; tag[u]=true; for(unsigned int i=0;i<e[u].size();i++){ int v=e[u][i].first; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if(tag[v]) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ cnt++; int t; do{ t=sta[top--]; res[t]=cnt; tag[t]=false; }while(t!=u); } } int main(){ scanf("%d%d%d",&n,&m1,&m2); memset(dis,0x3f3f,sizeof(dis)); for(int i=1;i<=n;i++) dis[i][i]=0; for(int i=1;i<=m1;i++){//a+1=b; int a,b; scanf("%d%d",&a,&b); //b<=a+1<=b e[a].push_back(make_pair(b,1)); e[b].push_back(make_pair(a,-1)); dis[a][b]=min(dis[a][b],1); dis[b][a]=min(dis[b][a],-1); } for(int i=1;i<=m2;i++){//a<=b int a,b; scanf("%d%d",&a,&b); e[b].push_back(make_pair(a,0)); dis[b][a]=min(dis[b][a],0); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) if(res[i]==res[k]&&dis[i][k]!=dis[0][0])//第二句剪枝快了不知道多少倍 for(int j=1;j<=n;j++) if(res[i]==res[j]&&dis[k][j]!=dis[0][0]) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); for(int i=1;i<=n;i++) if(dis[i][i]) {printf("NIE");exit(0);} for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(res[i]==res[j]) mx[res[i]]=max(mx[res[i]],dis[i][j]); for(int i=1;i<=cnt;i++) ans+=mx[i]+1; printf("%d",ans); }
分类:
差分约束
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 腾讯ima接入deepseek-r1,借用别人脑子用用成真了~
· [翻译] 为什么 Tracebit 用 C# 开发