【算法提高——第三讲(二)】图论(4)

简介: 【算法提高——第三讲(二)】图论(4)

3.13 欧拉回路和欧拉路径

3.13.1 1123. 铲雪车

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
int main()
{
    double x1,y1,x2,y2;
    cin>>x1>>y1;
    double sum=0;
    while(cin>>x1>>y1>>x2>>y2)
    {
        double dx=x1-x2;
        double dy=y1-y2;
        sum+=sqrt(dx*dx+dy*dy)*2;
    }
    int minutes=round(sum/1000/20*60);
    int hours=minutes/60;
    minutes%=60;
    printf("%d:%02d\n",hours,minutes);
    return 0;
}

3.13.2 1184. 欧拉回路

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=100010,M=400010;
int type;
int n,m;
int ans[M],cnt;
int din[N],dout[N];
int h[N],e[M],ne[M],idx;
bool used[M];
void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void dfs(int u)
{
    for(int &i=h[u];i!=-1;)
    {
        if(used[i])
        {
            i=ne[i];
            continue;
        }
        used[i]=true;
        if(type==1) used[i^1]=true;
        int t;
        if(type==1)
        {
            t=i/2+1;
            if(i&1) t=-t;
        }
        else t=i+1;
        int j=e[i];
        i=ne[i];
        dfs(j);
        ans[++cnt]=t;
    }
}
int main()
{
    memset(h,-1,sizeof h);
    cin>>type;
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        if(type==1) add(b,a);
        din[b]++,dout[a]++;
    }
    if(type==1)
    {
        for(int i=1;i<=n;i++)
        {
            if(din[i]+dout[i]&1)
            {
                cout<<"NO"<<endl;
                return 0;
            }
        }
    }
    else
    {
        for(int i=1;i<=n;i++)
        {
            if(din[i]!=dout[i])
            {
                cout<<"NO"<<endl;
                return 0;
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(h[i]!=-1)
        {
            dfs(i);
            break;
        }
    }
    if(cnt<m)
    {
        cout<<"NO"<<endl;
        return 0;
    }
    cout<<"YES"<<endl;
    for(int i=cnt;i>0;i--) cout<<ans[i]<<" ";
    return 0;
}

3.13.3 1124. 骑马修栅栏

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=510,M=1100;
int n=500,m;
int g[N][N];
int ans[M],cnt;
int d[N];
void dfs(int u)
{
    for(int i=1;i<=n;i++)
    {
        if(g[u][i])
        {
            g[u][i]--,g[i][u]--;
            dfs(i);
        }
    }
    ans[++cnt]=u;
}
int main()
{
    cin>>m;
    while(m--)
    {
        int a,b;
        cin>>a>>b;
        g[a][b]++,g[b][a]++;
        d[a]++,d[b]++;
    }
    int start=1;
    while(!d[start]) start++;
    for(int i=1;i<=n;i++)
    {
        if(d[i]%2)
        {
            start=i;
            break;
        }
    }
    dfs(start);
    for(int i=cnt;i>0;i--) cout<<ans[i]<<endl;
    return 0;
}

3.13.4 1185. 单词游戏

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=30;
int t,n;
int din[N],dout[N];
int p[N];
bool st[N];
int findP(int x)
{
    if(p[x]!=x) return p[x]=findP(p[x]);
    return p[x];
}
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n;
        memset(din,0,sizeof din);
        memset(dout,0,sizeof dout);
        memset(st,0,sizeof st);
        for(int i=0;i<26;i++) p[i]=i;
        string str;
        for(int i=0;i<n;i++)
        {
            cin>>str;
            int a=str[0]-'a',b=str[str.length()-1]-'a';
            dout[a]++,din[b]++;
            st[a]=true,st[b]=true;
            p[findP(a)]=findP(b);
        }
        bool flag1=true,flag2=true;
        int start=0,ed=0;
        for(int i=0;i<26;i++)
        {
            if(din[i]!=dout[i])
            {
                flag1=false;
                if(din[i]-dout[i]==1)
                    ed++;
                else if(dout[i]-din[i]==1)
                    start++;
                else
                {
                    flag2=false;
                    break;
                }
            }
        }
        int t=findP(0);
        for(int i=1;i<26;i++)
        {
            if(st[i]&&findP(i)!=t)
            {
                flag1=false;
                break;
            }
        }
        if(flag1||flag2&&start==1&&ed==1)
            cout<<"Ordering is possible."<<endl;
        else
            cout<<"The door cannot be opened."<<endl;
    }
    return 0;
}

3.14 拓扑排序

3.14.1 1191. 家谱树

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=110,M=10010;
int n;
int d[N];
vector<int> ans;
int h[N],e[M],ne[M],idx;
void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void topsort()
{
    queue<int> q;
    for(int i=1;i<=n;i++)
    {
        if(d[i]==0) q.push(i);
    }
    while(q.size())
    {
        int t=q.front();
        q.pop();
        ans.push_back(t);
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            d[j]--;
            if(d[j]==0) q.push(j);
        }
    }
}
int main()
{
    memset(h,-1,sizeof h);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        while(true)
        {
            int x;
            cin>>x;
            if(x==0) break;
            add(i,x);
            d[x]++;
        }
    }
    topsort();
    for(int i=0;i<ans.size();i++)
    {
        cout<<ans[i]<<" ";
    }
    return 0;
}

3.14.2 1192. 奖金

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
const int N=10010,M=20010;
int n,m;
int d[N];
int h[N],e[M],ne[M],idx;
void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int topsort()
{
    int res=0,cnt=0;
    queue<PII> q;
    for(int i=1;i<=n;i++)
    {
        if(d[i]==0)
        {
            q.push(make_pair(i,100));
            res+=100;
            cnt++;
        }
    }
    while(q.size())
    {
        PII t=q.front();
        q.pop();
        for(int i=h[t.first];i!=-1;i=ne[i])
        {
            int j=e[i];
            d[j]--;
            if(d[j]==0)
            {
                res+=t.second+1;
                q.push(make_pair(j,t.second+1));
                cnt++;
            }
        }
    }
    if(cnt<n) return -1;
    return res;
}
int main()
{
    memset(h,-1,sizeof h);
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin>>a>>b;
        add(b,a);
        d[a]++;
    }
    int t=topsort();
    if(t==-1) cout<<"Poor Xed"<<endl;
    else cout<<t<<endl;
    return 0;
}

3.14.3 164. 可达性统计

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=30010;
int n,m;
int d[N];
vector<int> seq;
bitset<N> f[N];
int h[N],e[N],ne[N],idx;
void add(int a,int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
void topsort()
{
    queue<int> q;
    for(int i=1;i<=n;i++)
    {
        if(d[i]==0)
        {
            q.push(i);
            seq.push_back(i);
        }
    }
    while(q.size())
    {
        int t=q.front();
        q.pop();
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            d[j]--;
            if(d[j]==0)
            {
                q.push(j);
                seq.push_back(j);
            }
        }
    }
}
int main()
{
    ios::sync_with_stdio(0);
    memset(h,-1,sizeof h);
    cin>>n>>m;
    for(int i=0;i<m;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        d[b]++;
    }
    topsort();
    for(int i=n-1;i>=0;i--)
    {
        int j=seq[i];
        f[j][j]=1;
        for(int k=h[j];k!=-1;k=ne[k])
            f[j]|=f[e[k]];
    }
    for(int i=1;i<=n;i++) cout<<f[i].count()<<endl;
    return 0;
}

3.14.4 456. 车站分级

image.png


代码:


#include<bits/stdc++.h>
using namespace std;
const int N=2010,M=1000010;
int n,m;
int d[N];
bool stop[N];
vector<int> seq;
int dis[N];
int h[N],e[M],w[M],ne[M],idx;
void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
void topsort()
{
    queue<int> q;
    for(int i=1;i<=n+m;i++)
    {
        if(d[i]==0)
        {
            q.push(i);
            seq.push_back(i);
        }
    }
    while(q.size())
    {
        int t=q.front();
        q.pop();
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            d[j]--;
            if(d[j]==0)
            {
                q.push(j);
                seq.push_back(j);
            }
        }
    }
}
int main()
{
    memset(h,-1,sizeof h);
    cin>>n>>m;
    for(int i=1;i<=m;i++)
    {
        int s;
        cin>>s;
        int start,ed;
        memset(stop,0,sizeof stop);
        for(int j=0;j<s;j++)
        {
            int x;
            cin>>x;
            if(j==0) start=x;
            if(j==s-1) ed=x;
            stop[x]=true;
        }
        int vir=n+i;
        for(int j=start;j<=ed;j++)
        {
            if(stop[j])
            {
                add(vir,j,1);
                d[j]++;
            }
            else
            {
                add(j,vir,0);
                d[vir]++;
            }
        }
    }
    topsort();
    for(int i=1;i<=n;i++) dis[i]=1;
    for(int i=0;i<seq.size();i++)
    {
        int t=seq[i];
        for(int j=h[t];j!=-1;j=ne[j])
        {
            int k=e[j];
            dis[k]=max(dis[k],dis[t]+w[j]);
        }
    }
    set<int> eq;
    for(int i=1;i<=n;i++)
        eq.insert(dis[i]);
    cout<<eq.size();
    return 0;
}

相关文章
|
3月前
|
JSON 算法 数据挖掘
基于图论算法有向图PageRank与无向图Louvain算法构建指令的方式方法 用于支撑qwen agent中的统计相关组件
利用图序列进行数据解读,主要包括节点序列分析、边序列分析以及结合节点和边序列的综合分析。节点序列分析涉及节点度分析(如入度、出度、度中心性)、节点属性分析(如品牌、价格等属性的分布与聚类)、节点标签分析(如不同标签的分布及标签间的关联)。边序列分析则关注边的权重分析(如关联强度)、边的类型分析(如管理、协作等关系)及路径分析(如最短路径计算)。结合节点和边序列的分析,如子图挖掘和图的动态分析,可以帮助深入理解图的结构和功能。例如,通过子图挖掘可以发现具有特定结构的子图,而图的动态分析则能揭示图随时间的变化趋势。这些分析方法结合使用,能够从多个角度全面解读图谱数据,为决策提供有力支持。
147 0
|
8月前
|
算法 数据挖掘 定位技术
算法必备数学基础:图论方法由浅入深实践与应用
算法必备数学基础:图论方法由浅入深实践与应用
|
9月前
|
算法 Python
Python中实现图论算法
Python中实现图论算法 “【5月更文挑战第20天】”
66 3
|
9月前
|
机器学习/深度学习 安全 算法
【图论】【割点】【C++算法】928. 尽量减少恶意软件的传播 II
【图论】【割点】【C++算法】928. 尽量减少恶意软件的传播 II
|
9月前
|
人工智能 算法 BI
【图论】【 割边】【C++算法】1192. 查找集群内的关键连接
【图论】【 割边】【C++算法】1192. 查找集群内的关键连接
|
9月前
|
机器学习/深度学习 算法 测试技术
【深度优先】【图论】【C++算法】2045. 到达目的地的第二短时间
【深度优先】【图论】【C++算法】2045. 到达目的地的第二短时间
|
9月前
|
安全 算法 测试技术
【图论】【并集查找】【C++算法】928. 尽量减少恶意软件的传播 II
【图论】【并集查找】【C++算法】928. 尽量减少恶意软件的传播 II
|
9月前
|
算法 测试技术 C++
【动态规划】【图论】【C++算法】1928规定时间内到达终点的最小花费
【动态规划】【图论】【C++算法】1928规定时间内到达终点的最小花费
|
9月前
|
算法 测试技术 C++
【动态规划】【图论】【C++算法】1575统计所有可行路径
【动态规划】【图论】【C++算法】1575统计所有可行路径
|
9月前
|
算法 C++ NoSQL

热门文章

最新文章