2

一些神奇的(优化)板子——来自Loi_black的博客

deque<int>q;
void spfa(int s)
{
    for(int i=1;i<=n;i++)
        d[i]=1e9;
    d[s]=0;
    q.push_back(s);
    used[s]=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop_front();
        used[x]=0;
        for(int i=first[x];i;i=next[i])
        {
            int u=hh[i].t;
            if(d[u]>d[x]+hh[i].c)
            {
                d[u]=d[x]+hh[i].c;
                if(!used[u])
                {
                    used[u]=1;
                    if(!q.empty())
                    {
                        if(d[u]<d[q.front()])
                            q.push_front(u);
                        else
                            q.push_back(u);
                    }
                    else
                        q.push_back(u);
                }
            }
        }
    }
}   
//spfa+(slf优化)
int tim[maxn];
bool spfa(int s)
{
    d[s]=0;
    q.push(s);
    used[s]=1;
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        used[x]=0;
        for(int i=first[x];i;i=next[i])
        {
            int u=hh[i].t;
            if(d[u]>d[x]+hh[i].c)
            {
                d[u]=d[x]+hh[i].c;
                if(!used[u])
                {
                    if(++tim[u]>n)
                        return false;
                    q.push(u);
                    used[u]=1;
                }
            }
        }
    }
    return true;
}

//spfa判负环
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;
const int maxn=200005;
struct dqs
{
    int f,t,c;
}hh[maxn];
struct dqm
{
    int num,dis;
};
bool operator <(dqm a,dqm b)
{
    return a.dis>b.dis;
}
int tot=0,first[maxn],next[maxn],d[maxn];
bool used[maxn];
void build(int f,int t,int c)
{
    hh[++tot]=(dqs){f,t,c};
    next[tot]=first[f];
    first[f]=tot;
}
priority_queue<dqm>q;
void dij(int s)
{
    d[s]=0;
    q.push({s,d[s]});
    while(!q.empty())
    {
        int head = q.top().num;
        q.pop();
        used[head]=1;
        for(int i=first[head];i;i=next[i])
        {
            int u=hh[i].t;
            if(d[u]>d[head]+hh[i].c)
            {
                d[u]=d[head]+hh[i].c;
                if(!used[u])
                    q.push((dqm){u,d[u]});
            }
        }
    }
}
int main()
{
    int n,m,s,e;
    scanf("%d%d%d%d",&n,&m,&s,&e);
    ......
}
//dijkstra+ 堆
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=250010;
struct dqs
{
    int f,t,c;
}hh[maxn<<1];
int tot=0,fa[maxn][31],next[maxn],first[maxn],f[maxn],d[maxn];
void build(int ff,int tt,int cc)
{
    hh[++tot]=(dqs){ff,tt,cc};
    next[tot]=first[ff];
    first[ff]=tot;
}
int deep[maxn];
void dfs(int x,int sd)
{
    deep[x]=sd;
    int u;
    for(int i=first[x];i;i=next[i])
    {
        u=hh[i].t;
        if(!deep[u]&&u)
        {
            f[u]=x;
            d[u]=d[x]+hh[i].c;
            dfs(u,sd+1);
        }
    }
}
int lca(int x,int y)
{
    if(deep[x]<deep[y])
    swap(x,y);
    int deepcha=deep[x]-deep[y];
    for(int i=0;i<=30;i++)
    {
        if(1<<i&deepcha)
        x=fa[x][i];
    }
    for(int i=30;i>=0;i--)
    {
        if(fa[x][i]!=fa[y][i])
        {
            x=fa[x][i];
            y=fa[y][i];
        }
    }
    if(x!=y)
        return f[x];
    return x;
}
int main()
{
    int n;
    scanf("%d",&n);
    int u,v,c;
    for(int i=1;i<n;i++)
    {
        scanf("%d%d%d",&u,&v,&c);
        build(u,v,c);
        build(v,u,c);
    }
    dfs(0,0);
    for(int i=0;i<n;i++)
        fa[i][0]=f[i];
    for(int j=1;j<=20;j++)
    for(int i=1;i<=n;i++)
        fa[i][j]=fa[fa[i][j-1]][j-1];
    int m;
    scanf("%d",&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&u,&v);
        int xx=lca(u,v);
        printf("%d\n",d[u]+d[v]-2*d[xx]);
    }
    return 0;
}

//倍增lca
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<queue>
using namespace std;
const int maxn=200005;
struct dqs
{
    int f,t,c;
}hh[maxn];
int tot=0,first[maxn],next[maxn],du[maxn];
void build(int f,int t)
{
    hh[++tot]=(dqs){f,t};
    next[tot]=first[f];
    first[f]=tot;
}
queue<int>q;
void tp()
{
    while(!q.empty())
    {
        int x=q.front();
        q.pop();
        printf("%d ",x);
        for(int i=first[x];i;i=next[i])
        {
            int u=hh[i].t;
            du[u]--;
            if(!du[u])
            q.push(u);
        }
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;
        while(true)
        {
            scanf("%d",&x);
            if(x==0)
            break;
            build(i,x);
            du[x]++;
        }
    }
    for(int i=1;i<=n;i++)
        if(!du[i])
            q.push(i);
    tp();
    return 0;
}
//拓扑排序
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=10005;
struct dqs
{
    int f,t;
}hh[maxn];
int tot=0;
int first[maxn],next[maxn];
void build(int f,int t)
{
    hh[++tot]=(dqs){f,t};
    next[tot]=first[f];
    first[f]=tot;
}
int dfn[maxn],low[maxn],stack[maxn],size[maxn],du[maxn],jlqlt[maxn];
bool in_stack[maxn];
int tot1=0,cnt=0,snum=0;
void group(int x)
{
    dfn[x]=low[x]=++tot1;
    stack[++snum]=x;
    in_stack[x]=1;
    for(int i=first[x];i;i=next[i])
    {
        int u=hh[i].t;
        if(!dfn[u])
        {
            group(u);
            low[x]=min(low[x],low[u]);
        }
        else if(in_stack[u])
            low[x]=min(low[x],dfn[u]);
    }
    if(dfn[x]==low[x])
    {
        cnt++;
        while(true)
        {
            jlqlt[stack[snum]]=cnt;
            in_stack[stack[snum]]=0;
            size[cnt]++;
            snum--;
            if(stack[snum+1]==x)
                break;
        }
    }
}
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        build(a,b);
    }
    for(int i=1;i<=n;i++)
        if(!dfn[i])
            group(i);
    for(int i=1;i<=n;i++)
        for(int j=first[i];j;j=next[j])
        {
            int u=hh[j].t;
            if(jlqlt[i]!=jlqlt[u])
                du[jlqlt[i]]++;
        }
    int sum1=0,sum2=0,x;
    for(int i=1;i<=cnt;i++)
    {
        if(size[i]>1)
            sum1++;
        if(!du[i])
        {
            sum2++;
            x=i;        
        }
    }
    printf("%d\n",sum1);
    if(sum2==1&&size[x]!=1)
    {
        for(int i=1;i<=n;i++)
        {
            if(jlqlt[i]==x)
            printf("%d ",i);
        }
    }
    else
    printf("-1\n");
    return 0;
} 

//trajan
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=200005; 
long long tmp[maxn],a[maxn];
long long ans=0;
void merge(int l,int mid,int r)
{
    int i=l,j=mid+1,k=l;
    while(i<=mid&&j<=r)
    {
        if(a[i]>a[j])
        {
            tmp[k++]=a[j++];
            ans+=mid+1-i;
        }
        else
            tmp[k++]=a[i++]; 
    }
    while(i<=mid)
        tmp[k++]=a[i++];
    while(j<=r)
        tmp[k++]=a[j++];
    for(int i=l;i<=r;i++)
        a[i]=tmp[i];
}
void merge_sort(int l,int r)
{
    if(l<r)
    {
        int mid=(l+r)>>1;
        merge_sort(l,mid);
        merge_sort(mid+1,r);
        merge(l,mid,r);
    } 
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    merge_sort(1,n);
    for(int i=1;i<=n;i++)
        cout<<a[i]<<" ";
    cout<<endl;
    printf("%lld",ans);
}

//归并排序
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int maxn=200005;
int heap[maxn],cnt=0;
void push(int x)
{
    cnt++;
    int now=cnt;
    heap[now]=x;
    while(now>1)
    {
        if(heap[now]<heap[now/2])
        {
            swap(heap[now],heap[now/2]);
            now/=2;
        }
        else break;
    }
}
void pop()
{
    heap[1]=heap[cnt];
    int now=1;
    while(now*2+1<=cnt)
    {
        int l=now*2,r=now*2+1;
        if(heap[l]<heap[now])
        {
            if(heap[r]<heap[l])
                swap(l,r);
            swap(heap[l],heap[now]);
            now=l;
        }
        else if(heap[r]<heap[now])
        {
            swap(heap[r],heap[now]);
            now=r;
        }
        else break;
    }
    cnt--;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        int x;
        scanf("%d",&x);
        push(x);
    }
    for(int i=1;i<=n;i++)
    {
        printf("%d ",heap[1]);
        pop();
    }
}

//手打最小堆(最大堆同理)

 

posted @ 2017-10-08 10:00  DDYYZZ  阅读(431)  评论(0编辑  收藏  举报