拓扑结构+差分约束+SLF最长路+扩欧

Posted 钟钟终

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了拓扑结构+差分约束+SLF最长路+扩欧相关的知识,希望对你有一定的参考价值。

倦怠,但还不能休息,我的牌还没有到手~

E. Exchanging Gifts

997m过了,超时了就多交几次就可能过吧……可以把vector改成链式前向行,vector改为二维数组,会优化100ms左右。

#include <bits/stdc++.h>
#define endl '\\n'
//#define int long long
#define ll long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
#define re register
using namespace std;
const int N =1e6+5;
const int inf=1e18;
const int mod=998244353;
const double eps=1e-8;
int n,ind[N];
ll num[N];
bool vis[N],tag[N];
vector<int>v[N],e[N];
unordered_map<ll,ll>mp;
inline void bfs()

    queue<int>q;
    q.push(n);
    while(!q.empty())
    
        int cur=q.front();q.pop();
        if(vis[cur]) continue;
        vis[cur]=1;
        for(int v:e[cur])
        
            ind[v]++;
            q.push(v);
        
    
    num[n]=1;
    q.push(n);
    while(!q.empty())
    
        int u=q.front();q.pop();
        for(int v:e[u])
        
            num[v]+=num[u];
            ind[v]--;
            if(!ind[v]) q.push(v);
        
        if(tag[u])
        
            for(auto x:v[u])
                mp[x]+=num[u];
        
    

inline void solve()

    cin>>n;
    for(re int i=0;i<=n;i++)
    
        e[i].clear();v[i].clear();
        ind[i]=tag[i]=num[i]=vis[i]=0;
    
    mp.clear();
    for(re int i=1;i<=n;i++)
    
        int op;cin>>op;
        if(op==1)
        
            tag[i]=1;
            int m;cin>>m;
            for(int j=1;j<=m;j++)
            
                int x;cin>>x;
                v[i].push_back(x);
            
        
        else
        
            int x,y;cin>>x>>y;
            e[i].push_back(x);e[i].push_back(y);
        
    
    bfs();
    ll sum=0,mx=0;
    for(auto x:mp)
        sum+=x.second,mx=max(mx,x.second);

    if(mx>=sum-mx) cout<<2ll*(sum-mx)<<endl;
    else cout<<sum<<endl;

signed main()

    ios;
    int T;
    cin>>T;
    while(T--)
        solve();
    return 0;


A. Artful Paintings

二分+差分约束
思路:
1.两个未知量可能想到扩欧,本题是毫不相关。而且本题三个变量,需要枚举出sum[n]的值
2.采用求最长路的SLF双端队列实现操作。
4.四类见图方式:sum[r]-sum[l-1]>=ksum[l-1]-sum[r]>=k-sum[n]sum[i]-sum[i-1]>=0sum[i-1]-sum[i]>=-1sum[n]-sum[0]>=xsum[0]-sum[n]>=-n

#include <bits/stdc++.h>
#define endl '\\n'
//#define int long long
#define ll long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
#define re register
using namespace std;
const int N =7e5+5;
const int inf=1e18;
const int mod=998244353;
const double eps=1e-8;
int n,m1,m2,cnt;
struct border

    int l,r,w;
b1[N],b2[N];
int head[N],dis[N],vis[N],ct[N];
struct node

    int to,nxt,w;
e[N];
void add(int from,int to,int w)

    e[++cnt].to=to;
    e[cnt].nxt=head[from];
    e[cnt].w=w;
    head[from]=cnt;

int check(int x)         //求最长路

    for(int i=0;i<=n;i++) head[i]=-1,dis[i]=-1e9,vis[i]=ct[i]=0;
    cnt=0;
    for(int i=1;i<=m1;i++)
    
        int l=b1[i].l,r=b1[i].r,w=b1[i].w;
        add(l-1,r,w);
    
    for(int i=1;i<=m2;i++)
    
        int l=b2[i].l,r=b2[i].r,w=b2[i].w;
        add(r,l-1,w-x);
    
    for(int i=1;i<=n;i++)
    
        add(i-1,i,0);add(i,i-1,-1);
    
    add(0,n,x);add(n,0,-x);
    vis[0]=ct[0]=1;
    dis[0]=0;
    deque<int>q;
    q.push_back(0);
    while(!q.empty())
    
        int u=q.front();
        q.pop_front();
        vis[u]=0;
        for(int i=head[u];i!=-1;i=e[i].nxt)
        
            int v=e[i].to,w=e[i].w;
            if(dis[v]<dis[u]+w)
            
                dis[v]=dis[u]+w;
                ct[v]=ct[u]+1;
                if(ct[v]>n+1)
                    return 0;
                if(!vis[v])
                
                    vis[v]=1;
                    if(!q.empty()&&dis[v]>dis[q.front()])
                        q.push_front(v);
                    else
                        q.push_back(v);
                
            
        
    
    return 1;

void solve()

    cin>>n>>m1>>m2;
    for(int i=1;i<=m1;i++)
    
        int l,r,w;cin>>l>>r>>w;
        b1[i]=l,r,w;
    
    for(int i=1;i<=m2;i++)
    
        int l,r,w;cin>>l>>r>>w;
        b2[i]=l,r,w;
    
    int l=0,r=n,mid,ans;
    while(l<=r)
    
        mid=(l+r)/2;
        if(check(mid))
            r=mid-1,ans=mid;
        else
            l=mid+1;
    
    cout<<ans<<endl;

signed main()

    //ios;
    int T;
    cin>>T;
    while(T--)
        solve();
    return 0;


G - 01Sequence

要废了 。。。最短路都写错了 ,哭

#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
#define ll long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
#define re register
using namespace std;
const int N =7e5+5;
const int inf=1e18;
const int mod=998244353;
const double eps=1e-8;
int n,m,dis[N];
vector<PII>g[N];
bool vis[N];

void dij()

    for(int i=0;i<=n;i++) dis[i]=inf;
    dis[0]=0;
    priority_queue<PII,vector<PII>,greater<PII>>q;
    q.push(0,0);
    while(q.size())
    
        int u=q.top().second,d=q.top().first;
        q.pop();
        if(vis[u]) continue;
        vis[u]=1;
        for(auto x:g[u])
        
            int v=x.first,w=x.second;
            if(dis[v]>d+w)
            
                dis[v]=d+w;
                q.push(dis[v],v);
            
        
    


void solve()

    cin>>n>>m;
    for(int i=1; i<=m; i++)
    
        int l,r,x;cin>>l>>r>>x;
        x=r-l+1-x;
        g[l-1].push_back(r,x);
    
    for(int i=0; i<=n-1; i++)
    
        g[i].push_back(i+1,1);
        g[i+1].push_back(i,0);
    
    dij();
    for(int i=1; i<=n; i++)
        cout<<((dis[i]-dis[i-1])^1)<<" ";
    cout<<endl;

signed main()

    ios;
//    int T;
//    cin>>T;
//    while(T--)
    solve();
    return 0;


D. ConstructOR

思路:
很容易想到要构造的那个数肯定是d的倍数,同时二进制a、b中出现的1.
令k=a|b,此时k不一定是d的倍数,我们只需要找到一个k是d的倍数。
可得出方程:r=d-k%d,也就是说k需要减去这样一个数r才会是d的倍数。
因此:x==r(mod d),由于低位的1会重复,因此左移30位2^30*x==r(mod d)

#include <bits/stdc++.h>
#define endl '\\n'
#define int long long
//#define ll long long
#define ios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define PII pair<int,int>
#define re register
using namespace std;
const int以上是关于拓扑结构+差分约束+SLF最长路+扩欧的主要内容,如果未能解决你的问题,请参考以下文章

POJ.1752.Advertisement(差分约束 最长路SPFA)

HDU.1529.Cashier Employment(差分约束 最长路SPFA)

差分约束系统总结(转)

P1993 小K的农场

bzoj2330: [SCOI2011]糖果 (利用差分约束系统将之转换成最长路的问题)

差分约束