4/24 tarjin+差分约束

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4/24 tarjin+差分约束相关的知识,希望对你有一定的参考价值。

P1993 小 K 的农场
注意建图的方式,共有三种情况:
1.a-b>=c,
2.a-b<=c
3.a==c
需要统一格式,如果都是">=",就要跑最长路;相反,若是小于等于,就是最短路。
建图时由减数指向被减数,即为b指向a。

#include <bits/stdc++.h>

using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
int n,m,head[maxn],cnt,dist[maxn],num[maxn];
bool vis[maxn];
struct node

    int to,nxt,dis;
e[maxn];
void add(int u,int v,int w)

    e[++cnt].to=v;
    e[cnt].dis=w;
    e[cnt].nxt=head[u];
    head[u]=cnt;

queue<int>q;
bool spfa(int u)

    memset(dist,inf,sizeof(dist));
    dist[u]=0;
    q.push(u);
    vis[u]=1;
    num[u]=1;
    while(!q.empty())
    
        int u=q.front();q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=e[i].nxt)
        
            int v=e[i].to;
            if(dist[v]>dist[u]+e[i].dis)
            
                dist[v]=dist[u]+e[i].dis;
                num[v]++;
                if(num[v]>=n)
                
                    return 0;
                
                if(!vis[v])
                
                    q.push(v);
                    vis[v]=1;
                
            
        
    
    return 1;

signed main()

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)   //建立超级源点
    
        add(n+1,i,0);
    
    for(int k=1;k<=m;k++)
    
        int g;
        scanf("%d",&g);
        if(g==1)
        
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,-w);
        
        else if(g==2)
        
            int u,v,w;
            scanf("%d%d%d",&u,&v,&w);
            add(v,u,w);
        
        else
        
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v,0);
            add(v,u,0);
        
    
    if(spfa(n+1))
        cout<<"Yes"<<endl;
    else
        cout<<"No"<<endl;
    return 0;

找到图中强连通分量的个数,可将每个强连通分量看作一个点,类似缩点的思想:
1.记录他们的长度和入读
2.可记录每个分量中点的个数

#include <bits/stdc++.h>

using namespace std;
const int maxn=1e5+5;
int n,m,head[maxn],cnt,dfn[maxn],low[maxn],bl[maxn],tim;
int inq[maxn],v[maxn],nxt[maxn],tol,in[maxn],ans,du[maxn];
stack<int>q;
void add(int u,int v1)

    v[++cnt]=v1;
    nxt[cnt]=head[u];
    head[u]=cnt;

void tarjan(int u)

    dfn[u]=low[u]=++tim;
    q.push(u);
    inq[u]=1;
    for(int i=head[u];i;i=nxt[i])
    
        int v1=v[i];
        if(!dfn[v1])
        
            tarjan(v1);
            low[u]=min(low[u],low[v1]);
        
        else if(inq[v1])
            low[u]=min(low[u],dfn[v1]);
    
    if(dfn[u]==low[u])
    
        tol++;int tmp;
        do
            tmp=q.top();
            q.pop();
            inq[tmp]=0;
            in[tol]++;   //此强连通分量的点数
            bl[tmp]=tol;  //缩点操作
        while(tmp!=u);
    

int main()

    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    
        int u,v1;scanf("%d%d",&u,&v1);
        add(u,v1);
    
    for(int i=1;i<=n;i++)
    
        if(!dfn[i])
            tarjan(i);
    
    for(int f=1;f<=n;f++)
    
        for(int i=head[f];i;i=nxt[i])
        
            int vv=v[i];
            if(bl[f]!=bl[vv])
            
                du[bl[f]]++;
            
        
    
    int tt=0;
    for(int i=1;i<=tol;i++)
    
        if(!du[i])
        
            if(tt)
            
                cout<<0<<endl;
                return 0;
            
            tt=i;  //只能一个点出度为0
        
    
    cout<<in[tt]<<endl;
    return 0;

以上是关于4/24 tarjin+差分约束的主要内容,如果未能解决你的问题,请参考以下文章

P1993 小K的农场 - 差分约束

差分约束系统

HDU3592差分约束

P3275 [SCOI2011]糖果 && 差分约束

洛谷 P5960 模板差分约束算法(spfa)

差分约束