pat甲级 图论

本文涵盖了多种图论问题的解决方案,包括最短路径、团、最大团、简单回路、连通图等。涉及迪杰斯特拉算法、哈密顿路径、欧拉路径、最短时间路径等概念,并提供了C++实现。通过对图的遍历和搜索,展示了如何在实际问题中应用这些算法。
摘要由CSDN通过智能技术生成

A1154

#include<iostream>
#include<unordered_set>
using namespace std;

const int maxn=10010;



int n,m,k;

struct node            //设置边的结构,到时候通过访问两条边上的那个结点来判断颜色是相同?
{
    int a,b;
}Node[maxn];

int color[maxn];

int main()
{
    cin >> n >> m;
    for(int i=0; i<m; i++)
    {
        cin >> Node[i].a >> Node[i].b;
    }
    cin >> k;
    while(k--)
    {
        unordered_set<int> s;
        for(int i=0; i<n; i++)
        {
            cin >> color[i];
            s.insert(color[i]);
        }

        bool flag=true;
        for(int j=0; j<m; j++)
        {
            if(color[Node[j].a]==color[Node[j].b])
            {
                flag=false;
                break;
            }
        }
        if(flag==true)
            cout << s.size() << "-coloring" << endl;
        else
            cout << "No" << endl;
    }
}

A1150

#include<iostream>
#include<cstring>
using namespace std;

const int maxn=222;

const int INF=0x3f3f3f3f;     //设置最大值记住是4个3f

int d[maxn][maxn],n,m,k;

int vers[maxn];

bool st[maxn];

/*
    对于TS simple cycle满足4个要求:
    1.有长度即sum不为-1
    2.每个点都能访问到
    3.访问的点的个数时n+1
    4.第1个访问的点是最后一个访问的点
    
    对于(TS cycle)满足;
    1.有长度即sum不为-1
    2.每个点都能访问到
    3.第1个访问的点是最后一个访问的点
    
    对于(Not a TS cycle)满足:
    1.有长度即sum不为-1
    
    对于NA (Not a TS cycle)满足:
    1.没有长度

*/

int main()
{
    memset(d,INF,sizeof(d));
    cin >> n >> m;
    int temp1,temp2,temp3;
    for(int i=0; i<m; i++)
    {
        cin >> temp1 >> temp2 >> temp3;
        d[temp1][temp2]=d[temp2][temp1]=temp3;
    }
    cin >> k;
    int cnt;

    int maxzhi=INF,max_id;
    for(int T=1; T<=k; T++)
    {
        cin >> cnt;
        memset(st,false,sizeof(st));
        for(int i=0; i<cnt; i++)
        {
            cin >> vers[i];
            st[vers[i]]=true;
        }
        int sum=0;
        bool success=true;
        for(int i=0; i+1<cnt; i++)       //统计两个点直间的路径
        {
            if(d[vers[i]][vers[i+1]]==INF)      //如果某两个点之间没有路径的,则直接将sum设置为-1,这样对应的输出是NA (Not a TS cycle)
            {
                sum=-1; 
                success=false;
                break;
            }
            else
            {
                sum+=d[vers[i]][vers[i+1]];
            }
        }

        if(vers[0]!=vers[cnt-1])       //如果第1个顶点不是最后一个顶点,则表示不是回路
        {
            success=false;
        }

        //访问每个点是否已经访问了
        for(int j=1; j<=n; j++)
        {
            if(st[j]==false)
            {
                success=false;
                break;
            }
        }

        if(sum==-1)       //sum为-1,表示某两个点之间没有路径,则输出NA (Not a TS cycle)
        {
            printf("Path %d: NA (Not a TS cycle)\n",T);
        }
        else           //否则就表示有路径
        {
            if(!success)       //对于  如果第1个点不是最后一个点则表示不是回路+如果没有访问所有的点,也表示不是回路,则对应输出Path 3: 10 (Not a TS cycle)
            {
                printf("Path %d: %d (Not a TS cycle)\n",T,sum);
            }
            else
            {
                if(cnt!=n+1)      //如果访问的点数不是n+1就表示不是简单回路
                {
                    printf("Path %d: %d (TS cycle)\n",T,sum);
                } 
                else       //如果访问的点数是n+1则表示为简单回路
                {
                    printf("Path %d: %d (TS simple cycle)\n",T,sum);
                }
                if(maxzhi>sum)     //统计出所有回路中的路径的最小值
                {
                    maxzhi=sum;
                    max_id=T;
                }
            }
        }

    }
    printf("Shortest Dist(%d) = %d",max_id,maxzhi);
    return 0;
}

A1142

#include<iostream>
using namespace std;

/*
    题意:
    1.给出一个团,判断任意两个点之间是否有路径,如果是,则表示这是一个团
    2.最大团,表示从团外不能再找到一个点,使他到团内的每个点都有路径
    3.不是团,存再某两个点之间没有路径

*/

const int maxn=11111;

int n,m,k;

bool G[maxn][maxn];

int vers[maxn];

bool check_clique(int cnt)
{
    for(int i=0; i<cnt; i++)
    {
        for(int j=0; j<i; j++)
        {
            if(G[vers[i]][vers[j]]==false)
                return false;
        }
    }
    return true;
}

bool check_maximum(int cnt)
{
    bool st[maxn]={false};
    for(int i=0; i<cnt; i++)
    {
        st[vers[i]]=true;
    }

    for(int i=1; i<=n; i++)
    {
        if(!st[i])
        {
            bool success=true;

            for(int j=0; j<cnt; j++)
            {
                if(G[i][vers[j]]==false)
                {
                    success=false;
                    break;
                }
            }

            if(success)
                return false;
        }
    }
    return true;
}

int main()
{
    cin >> n >> m;
    int temp1,temp2;
    for(int i=0; i<m; i++)
    {
        cin >> temp1 >> temp2;
        G[temp1][temp2]=G[temp2][temp1]=true;
    }
    cin >> k;
    int cnt;
    while(k--)
    {
        cin >> cnt;
        for(int i=0; i<cnt; i++)
        {
            cin >> vers[i];
        }
        if(check_clique(cnt))
        {
            if(check_maximum(cnt))
            {
                cout << "Yes" << endl;
            }
            else
            {
                cout << "Not Maximal" << endl;
            }
        }
        else
            cout << "Not a Clique" << endl;
    }
}

A1039 (不是图论中的)

#include<iostream>
#include<map>
#include<set>
using namespace std;

const int maxn=40100;

//这就是个帅!!!!! 爷就是pat 甲级皇帝

map<string,set<int>> a;        //对于map前面放字符串,后面放set数组

int n,k;

string b[maxn];

int main()
{
    cin >> n >> k;      //
    int temp1,temp2,temp3;
    string temp4;
    for(int i=0; i<k; i++)
    {
        cin >> temp1 >> temp2;      //输入课程名称,在输入人数
        for(int j=0; j<temp2; j++)
        {
            cin >> temp4;        //以名字作为前面的值,而后面插入课程
            a[temp4].insert(temp1);
        }
    }
    for(int i=0; i<n; i++)
    {
        cin >> b[i];            //输入要输出的人名序列
    }

    for(int i=0; i<n; i++)
    {
        cout << b[i] << " " << a[b[i]].size();     //按照所给的人名序列进行输出
        for(set<int>::iterator it=a[b[i]].begin(); it!=a[b[i]].end(); it++)
            cout << " " << *it;
        cout << endl;
    }
}

A1139

/*
    题意:
    1.a钟意b , a需要找到c  ,然后c找到d  最后d找到b
    2.首先输出n,m 分别表示人数和朋友之间的关系数,注意n是>2,所以题中给出10,表示一个有9个人
    3.负号表示为女人,但是最后输出的话,不需要输出负号
    
    4.给出k个查询,每次查询给出两个人
    1.首先输出一个有多少对c,d可以帮助a找到b
    2.a男 b女 在后面的朋友对中必须保证第1个朋友是男 第2个朋友是女;如果a男 b男(基佬我擦)则后面朋友中的朋友c d必须是从男生中找
    
    3.最后输出的朋友对必须按照升序的方式进行输出

 

*/

#include<iostream>
#include<unordered_map>
#include<vector>
#include<algorithm>
using namespace std;

const int maxn=310;

unordered_map<string,int> mp;      //字符串--->代号

string num[maxn];     //代号-->字符串

vector<int> boys,girls;     //男生数组,女生数组

int g[maxn][maxn];        //g表示俩个人之间的朋友关系,其中用代号表示

int n,m,id=0,k;

int main()
{
    cin >> n >> m;
    string temp1,temp2,temp3,temp4;
    while(m--)
    {
        cin >> temp1 >> temp2;       //temp1,temp2表示输入的俩个字符串
        temp3=temp1;
        temp4=temp2;

        if(temp1.size()==5)      //将输入的两个字符串如果带有负号则去掉负号
            temp1=temp1.substr(1);
        if(temp2.size()==5)
            temp2=temp2.substr(1);

        if(mp.count(temp1)==0)   //为了避免重复,将输入的字符串和代号一一映射
        {
            mp[temp1]=++id;
            num[id]=temp1;
        }

        if(mp.count(temp2)==0)
        {
            mp[temp2]=++id;
            num[id]=temp2;
        }
        
        //用代号来将朋友之间的关系表示
        g[mp[temp1]][mp[temp2]]=g[mp[temp2]][mp[temp1]]=true;
        
        //分别将输入的字符串对应的代号放到男女不同的数组中
        if(temp3[0]=='-')
            girls.push_back(mp[temp1]);
        else
            boys.push_back(mp[temp3]);

        if(temp4[0]=='-')
            girls.push_back(mp[temp2]);
        else
            boys.push_back(mp[temp4]);
    }

    //在boys中消去重复的数字,先排序后消除,具体看下图,上面那个mp.count的判断只是为了一一映射字符串和代号,而对每次的输入都在boys和girls数组中都有添加,所以需要再次查重
    sort(boys.begin(),boys.end());    
    boys.erase(unique(boys.begin(),boys.end()),boys.end());
    sort(girls.begin(),girls.end());
    girls.erase(unique(girls.begin(),girls.end()),girls.end());

    cin >> k;
    string temp5,temp6;
    while(k--)
    {
        cin >> temp5 >> temp6;      //输入字符串
        vector<pair<string,string>> res;    //pair是固定法,具体如下图
        
        vector<int> p=boys,q=boys;  //先将p,q都设置为男生数组

        //那个是女生则把对应的p,q改为girls
        if(temp5[0]=='-')
        {
            p=girls;temp5=temp5.substr(1);
        }

        if(temp6[0]=='-')
        {
            q=girls;temp6=temp6.substr(1);
        }




        //通过mp,将输入的字符串的代号设为a,b
        int a=mp[temp5],b=mp[temp6];

        //c去遍历a的性别所对应的数组,同理,d去遍历b所对应的性别的数组
        for(int c:p)
            for(int d:q)     //a c d b之间的关系是
            {
                if(a!=c && a!=d && b!=c && b!=d && g[a][c] && g[c][d] && g[d][b])
                {
                    res.push_back({num[c],num[d]});
                }
            }

        sort(res.begin(),res.end());
        cout << res.size() << endl;

        for(auto p:res)
            cout << p.first << " " << p.second << endl;

    }
    return 0;

}

pair数组用法
unique+erase用法

A1134

#include<iostream>
#include<set>
using namespace std;

const int maxn=11111;

int n,m;

struct node
{
    int a,b;
}Node[maxn];

int main()
{
    cin >> n >> m;
    int temp1,temp2;
    for(int i=0; i<m; i++)
    {
        cin >> temp1 >> temp2;
        Node[i].a=temp1;
        Node[i].b=temp2;
    }

    int k;
    cin >> k;
    int temp3;
    for(int i=0; i<k; i++)
    {
        cin >> temp3;
        bool success=true;
        set<int> kk;
        int temp4;
        for(int j=0; j<temp3; j++)
        {
            cin >> temp4;
            kk.insert(temp4);
        }

        for(int q=0; q<m; q++)
        {
            if(kk.count(Node[q].a)==0 && kk.count(Node[q].b)==0)
            {
                success=false;
                break;
            }
        }

        if(success==true)
            cout << "Yes" << endl;
        else
            cout << "No" << endl;
    }
    return 0;
}

A1131

迪杰斯特拉算法堆优化

Example
给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为非负值。
请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。
输入格式
第一行包含整数n和m。
接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。
输出格式
输出一个整数,表示1号点到n号点的最短距离。
如果路径不存在,则输出-1。

3 3
1 2 2
2 3 1
1 3 4

输出结果为:3 表示从1号点到3号点的最短路径为3

#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

const int maxn=100010;

int h[maxn],e[maxn],ne[maxn],w[maxn],idx;        //这就是模板记住即可

int dist[maxn];

bool st[maxn];

typedef pair<int,int> PII;

int n,m;

void add(int a,int b,int c)
{
    e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}

int dijie()
{
    memset(dist,0x3f,sizeof(dist));
    priority_queue<PII,vector<PII>,greater<PII>> heap;

    heap.push({0,1});       //1号点 距离为0

    while(!heap.empty())
    {
        auto t=heap.top();
        heap.pop();

        int ver=t.second,distance=t.first;

        if(st[ver])
            continue;

        for(int i=h[ver]; i!=-1; i=ne[i])
        {
            int j=e[i];
            if(dist[j]>distance+w[i])
            {
                dist[j]=distance+w[i];
                heap.push({dist[j],j});
            }
        }
    }
    if(dist[n]==0x3f3f3f3f)
        return -1;
    return dist[n];
}

int main()
{
    cin >> n >> m;
    memset(h,-1,sizeof(h));

    int temp1,temp2,temp3;
    for(int i=0; i<m; i++)
    {
        cin >> temp1 >> temp2 >> temp3;   //temp1 temp2 temp3 分别表示两个端点+中间的路径
        add(temp1,temp2,temp3);
    }
    cout << dijie();
}

#include<iostream>
#include<queue>
#include<cstring>
using namespace std;

const int maxn=1000010;

int h[maxn],w[maxn],line[maxn],ne[maxn],idx,stop[maxn],e[maxn];

int cnt[maxn],dist[maxn],pre[maxn];

bool st[maxn];

string Info[maxn];

typedef pair<int,int> PII;

int n,m;

void add(int a,int b,int c,int d)     //套路,注意多加了line[idx]=d
{
    e[idx]=b,w[idx]=c,line[idx]=d,ne[idx]=h[a],h[a]=idx++;
}

string getNum(int x)
{
    char res[5];
    sprintf(res,"%04d",x);      //将数字x以 “%04d”的方式 读入到 res
    return res;
}

void dijie(int start,int end)
{
    memset(dist,0x3f,sizeof(dist));  
    memset(cnt,0x3f,sizeof(cnt));    //cnt表示换乘的次数
    memset(st,false,sizeof(st));

    dist[start]=cnt[start]=0;

    /*
        //升序队列
        priority_queue <int,vector<int>,greater<int> > q;
            3 //降序队列,大顶堆
        4 priority_queue <int,vector<int>,less<int> >q;
    */
    priority_queue<PII,vector<PII>,greater<PII>> heap;   //优先队列

    heap.push({0,start});    //将 距离0 和 起始点 放入到heap中

    while(!heap.empty())      //队列不为空
    {
        auto t=heap.top();

        heap.pop();

        int ver=t.second;      //top的点
        if(ver==end)    //提前结束循环
            break;
        if(st[ver])     //套路
            continue;

        st[ver]=true;    //套路



        for(int i=h[ver]; i!=-1; i=ne[i])    //套路
        {
            int j=e[i];
            if(dist[j]>dist[ver]+w[i])     //现在要判断的是j  拐点的是ver  
            {
                dist[j]=dist[ver]+w[i];
                pre[j]=ver;           //j的前驱结点是ver
                cnt[j]=cnt[ver]+1;
                Info[j]="Take Line#" + to_string(line[i]) + " from " + getNum(ver) + " to " + getNum(j) + ".";
                heap.push({dist[j],j});
            }
            else if(dist[j]==dist[ver]+w[i])  //如果距离相同,找到最小的换乘次数
            {
                if(cnt[j]>cnt[ver]+1)
                {
                    cnt[j]=cnt[ver]+1;
                    pre[j]=ver;
                    Info[j]=" Take Line#" + to_string(line[i]) + " from " + getNum(ver) + " to " + getNum(j) + ".";
                }
            }
        }
    }
    cout << dist[end] << endl;      //直接输出到达end这个点的最短路径
    vector<string> path;

    for(int i=end; i!=start; i=pre[i])
    {
        path.push_back(Info[i]);
    }

    for(int i=path.size()-1; i!=-1; i--)
        cout << path[i] << endl;
}

int main()
{
    cin >> n;
    int temp1;
    memset(h,-1,sizeof(h));             //h代表顶点,先都初始化为-1
    
    for(int i=1; i<=n; i++)    //n条线路
    {
        cin >> temp1;
        for(int q=0; q<temp1; q++)
        {
            cin >> stop[q];       //先输入车站
        }

        for(int j=0; j<temp1; j++)    //按照一种如下图的方式存储路径
            for(int k=0; k<j; k++)
            {
                int len;
                if(stop[0]!=stop[temp1-1])        //不是环路
                    len=j-k;
                else                        //是环路
                    len=min(j-k,k+temp1-1-j);

                add(stop[j],stop[k],len,i);
                add(stop[k],stop[j],len,i);
            }
    }

    int k;
    cin >> k;
    int start,end;
    while(k--)
    {
        cin >> start >> end;       //输入起终点
        dijie(start,end);
    }
    return 0;
}

在这里插入图片描述
在这里插入图片描述

A1126

#include<iostream>
using namespace std;

const int maxn=555;

int n,m;

bool g[maxn][maxn],st[maxn];

int d[maxn];      //统计每个点的度数

int dfs(int u)      //通过深度优先搜索,来判断从u结点出发,能到达其余的点的个数,如果为n则表示连通图,否则不是连通图
{
    st[u]=true;
    int res=1;

    for(int i=1; i<=n; i++)
    {
        if(!st[i] && g[u][i])
            res+=dfs(i);
    }

    return res;
}

int main()
{
    cin >> n >> m;
    int a,b;
    for(int i=0; i<m; i++)
    {
        cin >> a >> b;
        g[a][b]=g[b][a]=true;
        d[a]++,d[b]++;           //统计每个点的度数
    } 

    for(int i=1; i<=n; i++)
    {
        if(i!=1)
            cout << " ";
        cout << d[i];             //输出每个点的度数
    }

    cout << endl;

    if(dfs(1)==n)         //从图中某一个点出发,如果能到达其余的所有点则表示该图是连通的
    {
        int s=0;
        for(int i=1; i<=n; i++)
        {
            if(d[i]%2==0)
                s++;
        }
        if(s==n)
            cout << "Eulerian" << endl;
        else if(s+2==n)
            cout << "Semi-Eulerian" << endl;
        else
            cout << "Non-Eulerian" << endl;
    }
    else
        cout << "Non-Eulerian" << endl;
    return 0;
}

A1122

#include<iostream>
using namespace std;

const int maxn=420;     //对于这个值 如果出现    段错误  就直接扩大2然后去实验
    
int n,m;

bool g[maxn][maxn];

int main()
{
    cin >> n >> m;
    int a,b;
    for(int i=0; i<m; i++)
    {
        cin >> a >> b;
        g[a][b]=g[b][a]=true;
    }

    int k;
    cin >> k;
    int temp;
    while(k--)
    {
        cin >> temp;
        int vers[maxn];
        bool st[maxn]={false},success=true;

        for(int i=0; i<temp; i++)
        {
            cin >> vers[i];
            st[vers[i]]=true;
        }

        //少了判断每俩个点之间必须有边
        for(int i=0; i+1<temp; i++)
        {
            int a=vers[i],b=vers[i+1];
            if(g[a][b]==false)
            {
                success=false;
                break;
            }
        }

        if(vers[0]!=vers[temp-1])
        {
            success=false;
        }


        if(temp!=n+1)
        {
             success=false;
        }


        for(int i=1; i<=n; i++)
        {
            if(st[i]==false)
            {
                success=false;
                break;
            }
        }
        if(success)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

A1111

#include<iostream>
#include<cstring>
#include<vector>
using namespace std;

/*
本题目的意思是
    1.如果最短路径相同,则要时间最短的那条路线
    2.如果时间相同,则要通过的边数最少的那条路线
    3.最后如果1,2找的路径不同,则1表示最短的距离,则输出;2表示时间最短,也输出;如果路径相同,则只用输出一条路径即可

*/

const int maxn=1000;

int d1[maxn][maxn],d2[maxn][maxn];

bool st[maxn];

int dist1[maxn],dist2[maxn],pre[maxn];

int n,m;
int start,zhongdian;

//函数类型是pair<int,string>,其中 int表示最短的值  string表示的是路径
pair<int,string> dijie(int d1[][maxn], int d2[][maxn], int type)   
{
    memset(st,false,sizeof(st));
    memset(dist1,0x3f,sizeof(dist1));
    memset(dist2,0x3f,sizeof(dist2));

    dist1[start]=dist2[start]=0;

    for(int i=0; i<n; i++)
    {

        int u=-1;         //先找整个点中,权值最小的点
        for(int j=0; j<n; j++)
        {
            if(!st[j] && dist1[u]>dist1[j])
                u=j;
        }

        if(u==-1)
            break;
        else
            st[u]=true;

        for(int v=0; v<n; v++)
        {
            int w;
            if(type==0)        //type为0表示 最短路径+最短时间
                w=d2[u][v];
            else                //type为1表示  最短时间+最少边数
                w=1;
                
                if(dist1[v]>dist1[u]+d1[u][v])
                {
                    dist1[v]=dist1[u]+d1[u][v];
                    dist2[v]=dist2[u]+w;
                    pre[v]=u;
                }
                else if(dist1[v]==dist1[u]+d1[u][v])
                {
                    if(dist2[v]>dist2[u]+w)
                    {
                        dist2[v]=dist2[u]+w;
                        pre[v]=u;
                    }
                }

        }
    }

    pair<int,string> res;

    res.first=dist1[zhongdian];     //res.first值为 最短路径或者最短时间

    res.second=to_string(start);    //res.second表示路径

    vector<int> path;

    for(int i=zhongdian; i!=start; i=pre[i])
    {
        path.push_back(i);
    }

    for(int i=path.size()-1; i>=0; i--)
    {
        res.second+=" -> " + to_string(path[i]);
    }

    return res;     //返回值 是 pair<int,string>类型


}

int main()
{
    cin >> n >> m;
    
    //注意将d1,d2两个数组设置为0x3f而不设置为-1,是因为我们要找最小值,比如从u->v的某条路径是没有的,那么d1[u][v]表示0x3f,if(dist[v]>dist[u]+d1[u][v])我们找的是最短路径,所以自动不用理会那些没有值的路径
    memset(d1,0x3f,sizeof(d1));  
    memset(d2,0x3f,sizeof(d2));

    int a,b,c,d,e;
    while(m--)
    {
        cin >> a >> b >> c >> d >> e;
        
        //先进行一个单边的设置
        d1[a][b]=d;
        d2[a][b]=e;

        if(c!=1)  //如果c不为1,设置为双边
        {
            d1[b][a]=d;
            d2[b][a]=e;
        }
    }


    cin >> start >> zhongdian;  //输入起终点

    auto A=dijie(d1,d2,0);    //这个A表示的是 最短路径+最短时间
    auto B=dijie(d2,d1,1);    //这个B表示的是 最短时间+最少的边数 其中 参数d1是任意值 因为在迪杰斯特拉算法算法中表示的是边的条数 对于边的条数 是用 dist2来表示 并且权值为1

    if(A.second != B.second)  //如果路径不同,则分别输出
    {
        printf("Distance = %d: %s\n",A.first,A.second.c_str()); //  c_str()是固定用法
        printf("Time = %d: %s\n",B.first,B.second.c_str());
    }
    else   //表示路径相同
    {
        printf("Distance = %d; ",A.first);
        printf("Time = %d: %s\n",B.first,B.second.c_str());
    }
}

关于c_str的用法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值