bzoj 2788 [Poi2012]Festival 差分约束+tarjan+floyd

题目大意

有n个正整数X1,X2,...,Xn,再给出m1+m2个限制条件,限制分为两类:
1.给出a,b (1<=a,b<=n),要求满足Xa + 1 = Xb
2.给出c,d (1<=c,d<=n),要求满足Xc <= Xd
在满足所有限制的条件下,求集合{Xi}大小的最大值。

分析

差分约束,问题很新颖
注意到图有特殊性
限制1(1类边):双向边
限制2(2类边):单向边
我们考虑求强联通分量
连接两个强联通分量的边不可能是1类边(不然强联通就合起来了)
只可能是A<=B
只要保证A中最大值小于B中最小值,就可以使不同权值最多
一定是可以做到的
那么我们只需要对每个强联通求出答案再累加起来就好了
对于强联通中的2类边,一定是在一个环中的,一定都为一个权值(不然就分成两个连通块了)
这一部分的最长路跑出来是0
由于图中只有-1,0,1三种边
每个强联通中,
记D为任意两个点的 最长路的绝对值 的最大值
其实D就是最大权值和最小权值的差
所以每个连通块权值种类就是D+1

姿势

1.差分约束常常特判连边是否自环矛盾
2.floyd判负环可以一开始f[i][i]=0,跑floyd的时候不判i!=j!=k,跑完后看看f[i][i]有没有变
3.邻接矩阵建图注意重编时取max,min啥的
4.之前我tarjan一直是写错的

if(inst[y]) low[x]=min(low[x],dfn[y]);//注意这里是inst[i],因为有向图搜索顺序的问题,tarjan是可能跑到之前tarjan过的地方的,如果写if(dfn[y])这样会出bug
else if(!dfn[y]){
    tarjan(y);
    low[x]=min(low[x],low[y]);
}

5.spfa时用que[],inq[]
6.spfa时inc函数既写引用又写返回值,方便一些

solution
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <algorithm>
using namespace std;
const int M=607;
const int N=100007;
const int INF=2139062144;
 
inline int rd(){
    int x=0;bool f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
    for(;isdigit(c);c=getchar()) x=x*10+c-48; 
    return f?x:-x;
}
 
int n,m1,m2;
 
int g[M],te;
struct edge{
    int y,d,next;
}e[N<<1];
struct node{
    int x,y;
    node(int xx=0,int yy=0){x=xx;y=yy;}
}e1[N],e2[N];
 
void addedge(int x,int d,int y){
    e[++te].y=y;e[te].d=d;e[te].next=g[x];g[x]=te;
}
 
int dfn[M],low[M],tdfn;
int col[M],cnt;
int st[M],tot;
int vis[M];
int f[M][M];
int ans[M];
int inst[M];
 
void tarjan(int x){
    dfn[x]=low[x]=++tdfn;
    st[++tot]=x;
    inst[x]++;
    int p,y;
    for(p=g[x];p;p=e[p].next){
        y=e[p].y;
        if(inst[y]) low[x]=min(low[x],dfn[y]);//instack
        else if(!dfn[y]){
            tarjan(y);
            low[x]=min(low[x],low[y]);
        }
    }
    if(low[x]==dfn[x]){
        ++cnt;
        while(st[tot]!=x){
            inst[st[tot]]=0;
            col[st[tot--]]=cnt;
        }
        inst[st[tot]]=0;
        col[st[tot--]]=cnt;
    }
}
 
void floyd(){
    int i,j,k;
    for(k=1;k<=n;k++)
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    if(f[i][k]!=-INF&&f[k][j]!=-INF){
        f[i][j]=max(f[i][j],f[i][k]+f[k][j]);
    }
} 
 
 
 
int main(){
     
    n=rd(),m1=rd(),m2=rd();
     
    int i,j,x,y;
     
    for(i=1;i<=m1;i++){
        x=rd(),y=rd();
        if(x==y){//²é·ÖÔ¼Êø³£¼ûÌØÅÐ 
            puts("NIE");
            return 0;
        }
        e1[i]=node(x,y);
        addedge(x,1,y);
        addedge(y,-1,x);
    }
     
    for(i=1;i<=m2;i++){
        x=rd(),y=rd();
        e2[i]=node(x,y);
        addedge(x,0,y);
    }
     
    for(i=1;i<=n;i++)
    if(!dfn[i]) 
        tarjan(i);
     
    memset(f,128,sizeof(f));
    for(i=1;i<=m1;i++){
        x=e1[i].x,y=e1[i].y;
        if(col[x]==col[y]){
            f[x][y]=max(f[x][y],1);
            f[y][x]=max(f[y][x],-1);
        }
    }
    for(i=1;i<=m2;i++){
        x=e2[i].x,y=e2[i].y;
        if(col[x]==col[y]){
            f[x][y]=max(f[x][y],0);
        }
    }
    for(i=1;i<=n;i++) f[i][i]=0;//Åиº»·Óà 
     
    floyd();
     
    for(i=1;i<=n;i++) if(f[i][i]>0){
        puts("NIE");
        return 0;
    }
     
    for(i=1;i<=n;i++)
    for(j=1;j<=n;j++)
    if(col[i]==col[j]&&f[i][j]!=-INF) ans[col[i]]=max(ans[col[i]],abs(f[i][j]));///abs
     
    int sum=0;
    for(i=1;i<=cnt;i++) sum+=ans[i]+1;
     
    printf("%d\n",sum);
     
    return 0;
}

转载于:https://www.cnblogs.com/acha/p/6417237.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip 【备注】 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用!有问题请及时沟通交流。 2、适用人群:计算机相关专业(如计科、信息安全、数据科学与大数据技术、人工智能、通信、物联网、自动化、电子信息等)在校学生、专业老师或者企业员工下载使用。 3、用途:项目具有较高的学习借鉴价值,不仅适用于小白学习入门进阶。也可作为毕设项目、课程设计、大作业、初期项目立项演示等。 4、如果基础还行,或热爱钻研,亦可在此项目代码基础上进行修改添加,实现其他不同功能。 欢迎下载!欢迎交流学习!不清楚的可以私信问我! 毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip毕设新项目-基于Java开发的智慧养老院信息管理系统源码+数据库(含vue前端源码).zip
综合小区管理系统管理系统按照操作主体分为管理员和用户。管理员的功能包括报修管理、车位管理、车位分配管理、出入管理、字典管理、房屋管理、物业费缴纳管理、公告管理、物业人员投诉管理、我的私信管理、物业人员管理、用户管理、管理员管理。用户的功能包括管理部门以及部门岗位信息,管理招聘信息,培训信息,薪资信息等。该系统采用了Mysql数据库,Java语言,Spring Boot框架等技术进行编程实现。 综合小区管理系统管理系统可以提高综合小区管理系统信息管理问题的解决效率,优化综合小区管理系统信息处理流程,保证综合小区管理系统信息数据的安全,它是一个非常可靠,非常安全的应用程序。 管理员权限操作的功能包括管理公告,管理综合小区管理系统信息,包括出入管理,报修管理,报修管理,物业费缴纳等,可以管理操作员。 出入管理界面,管理员在出入管理界面中可以对界面中显示,可以对招聘信息的招聘状态进行查看,可以添加新的招聘信息等。报修管理界面,管理员在报修管理界面中查看奖罚种类信息,奖罚描述信息,新增奖惩信息等。车位管理界面,管理员在车位管理界面中新增。公告管理界面,管理员在公告管理界面查看公告的工作状态,可以对公告的数据进行导出,可以添加新公告的信息,可以编辑公告信息,删除公告信息。
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值