pat甲级图的判断

图的判断问题一般基于是给定一个场景或者是关于一个图的定义问题,然后输入一张图,给定一组数据要求判断这组数据是否是满足这个图的相关定义

比如给定一个哈密顿回路或者是最大团最小团问题或者是拓扑排序的问题

https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805500414115840

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 5 const int N=1e3+10;
 6 int n,m,k;
 7 int g[N][N];
 8 //vector<int>g[N];
 9 int cnt;
10 bool vis[N];
11 int ch;
12 void dfs(int u)
13 {
14     if(u==ch)
15     return ;
16     vis[u]=true;
17     for(int v=1;v<=u;v++)
18     {
19         if(!vis[v]&&g[u][v])
20         {
21             dfs(v);
22         }
23     }
24     
25 }
26 signed main()
27 {
28     IOS;
29     cin>>n>>m>>k;
30        for(int i=0;i<m;i++)
31     {
32         int s,t;
33         cin>>s>>t;
34         g[s][t]++;
35         g[t][s]++;
36         //g[s].push_back(t);
37         //g[t].push_back(s);
38     }
39      for(int i=0;i<k;i++)
40      {
41          cin>>ch;
42          cnt=0;
43          memset(vis,0,sizeof(vis));
44          for(int j=1;j<=n;j++)
45          {
46              if(j!=ch&&!vis[j])
47              {
48                  dfs(j);
49                  cnt++;
50              }
51          }
52          cout<<cnt-1<<endl;
53      }
54     return 0;
55 }

邻接矩阵做法;

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 5 const int N=1e3+10;
 6 int n,m,k;
 7 int g[N][N];
 8 //vector<int>g[N];
 9 int cnt;
10 bool vis[N];
11 int ch;
12 void dfs(int u)
13 {
14     if(u==ch)
15     return ;
16     vis[u]=true;
17     for(int v=1;v<=u;v++)
18     {
19         if(!vis[v]&&g[u][v])
20         {
21             dfs(v);
22         }
23     }
24     
25 }
26 signed main()
27 {
28     IOS;
29     cin>>n>>m>>k;
30        for(int i=0;i<m;i++)
31     {
32         int s,t;
33         cin>>s>>t;
34         g[s][t]++;
35         g[t][s]++;
36         //g[s].push_back(t);
37         //g[t].push_back(s);
38     }
39      for(int i=0;i<k;i++)
40      {
41          cin>>ch;
42          cnt=0;
43          memset(vis,0,sizeof(vis));
44          for(int j=1;j<=n;j++)
45          {
46              if(j!=ch&&!vis[j])
47              {
48                  dfs(j);
49                  cnt++;
50              }
51          }
52          cout<<cnt-1<<endl;
53      }
54     return 0;
55 }

https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805351814119424

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long 
 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 5 const int N=210;
 6 int g[N][N];
 7 int a[N];
 8 int n,m;
 9 int q;
10 int tmp;
11 set<int>qs;
12 signed main()
13 {
14     IOS;
15     cin>>n>>m;
16     int s,t;
17     for(int i=1;i<=m;i++)
18     {
19         cin>>s>>t;
20         g[s][t]=g[t][s]=1;
21     }
22     cin>>q;
23     while(q--)
24     {
25         bool flag1=true;
26         bool flag2=true;
27         qs.clear();
28         memset(a,0,sizeof(a));
29         cin>>tmp;
30         for(int i=1;i<=tmp;i++)
31         {
32             cin>>a[i];
33             qs.insert(a[i]);
34         }
35         if(tmp-1!=n||qs.size()!=n||a[1]!=a[tmp])
36         {
37             flag1=false;
38         }
39         for(int i=1;i<tmp;i++)
40         {
41             if(g[a[i]][a[i+1]]==0)
42             {
43                   flag2=false;
44                   break;
45             }
46         }
47         if(flag1&&flag2)
48         {
49             cout<<"YES"<<endl;
50         }
51         else{
52             cout<<"NO"<<endl;
53         }
54     }
55     return 0;
56 }

https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805349851185152

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
 5 const int N=510;
 6 vector<int>g[N];
 7 int n,m;
 8 int cnt;
 9 int x;
10 bool vis[N];
11 void dfs(int u)
12 {
13     vis[u]=true;
14     cnt++;
15     for(int v=0;v<g[u].size();v++)
16     {
17         if(!vis[g[u][v]])
18         {
19             dfs(g[u][v]);
20         }
21     }
22 }
23 signed main()
24 {
25     IOS;
26     cin>>n>>m;
27     int s,t;
28     for(int i=0;i<m;i++)
29     {
30         cin>>s>>t;
31         g[s].push_back(t);
32         g[t].push_back(s);
33     }
34        for(int i=1;i<=n;i++)
35        {
36            if(g[i].size()%2==0)
37            {
38                x++;
39            }
40            cout<<g[i].size();
41            if(i<n)
42            cout<<" ";
43        }
44        dfs(1);
45        cout<<endl;
46        if(cnt==n&&x==n)
47        {
48            cout<<"Eulerian";
49        }
50        else if(cnt==n&&x==n-2)
51        {
52            cout<<"Semi-Eulerian";
53        }
54        else
55        {
56            cout<<"Non-Eulerian";
57        }
58     return 0;
59 }

https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805343979159552

 1 //主要是败在读题上其实
 2 //这道题的意思区别团和最大团
 3 //所谓团就是给定的一组序列的点都是一一相邻的
 4 //最大团是不能在找一个点来加入集合序列形成最大团
 5 //换言之就是在所有的点中不存在一个点在和集合中的点一一相邻,也就是如果除去集合中的点
 6 //如果在存在一个点与集合中的点一一相邻那他就不是最大团
 7 //所以说本题的做法是建一个hash来储存不在集合中的点
 8 //先遍历集合是否是团
 9 //在遍历没有在集合中的点是否和集合中的点一一相邻
10 #include<bits/stdc++.h>
11 using namespace std;
12 #define int long long 
13 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
14 const int N=210;
15 int g[N][N];
16 int n,m;
17 int q;
18 int k;
19 signed main()
20 {
21     IOS;
22     cin>>n>>m;
23     int s,t;
24     for(int i=1;i<=m;i++)
25     {
26         cin>>s>>t;
27         g[s][t]=g[t][s]=1;
28     }
29     cin>>q;
30     while(q--)
31     {
32         int a[N]={0};
33         bool flag1=true;
34         bool flag2=true;
35         int hasha[N]={0};
36         cin>>k;
37         for(int i=1;i<=k;i++)
38         {
39             cin>>a[i];
40             hasha[a[i]]=1;
41         }
42         for(int i=1;i<=k;i++)
43         {
44             if(!flag1)
45                 break;
46             for(int j=i+1;j<=k;j++)
47             {
48                 if(!g[a[i]][a[j]])
49                 {
50                     flag1=false;
51                     cout<<"Not a Clique"<<endl;
52                     break;
53                 }
54             }
55         }
56         if(!flag1)
57             continue;
58         for(int i=1;i<=n;i++)
59         {
60             if(!hasha[i])
61             {
62                 for(int j=1;j<=k;j++)
63                 {
64                     if(!g[i][a[j]])
65                         break;
66                     if(j==k)
67                         flag2=false;
68                 }
69             }
70             if(!flag2)
71             {
72                 cout<<"Not Maximal"<<endl;
73                 break;
74             }
75         }
76         if(flag2)
77             cout<<"Yes"<<endl;
78     }
79     return 0;
80 }

https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805346428633088

 1 //首先解读题意
 2 //本题的大意是图中的边至少和给定集合中的一个点相关联,则称这个图为点覆盖图
 3 //本题就是判断是否是点覆盖问题
 4 //需要注意的细节
 5 //g[i][j]表示i点和j边相关联
 6 //存一个哈希表表示这个点和这个边相关联
 7 //然后在遍历所有的边,如果有!hasha[i]就说明对于这条边来讲没有一个点出自集合中,就判断为No
 8 //否则判断为Yes
 9 #include<bits/stdc++.h>
10 using namespace std;
11 #define int long long 
12 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
13 const int N=1e4+10;
14 vector<int>g[N];
15 int n,m,q;
16 int k;
17 signed main()
18 {
19     IOS;
20     cin>>n>>m;
21     int s,t;
22     for(int i=0;i<m;i++)
23     {
24         cin>>s>>t;
25         g[s].push_back(i);
26         g[t].push_back(i);
27     }
28     cin>>q;
29     while(q--)
30     {
31         bool flag=true;
32         vector<int>hasha(m,0);
33         cin>>k;
34         int tmp;
35         for(int i=0;i<k;i++)
36         {
37             cin>>tmp;
38             for(int j=0;j<g[tmp].size();j++)
39             {
40                 hasha[g[tmp][j]]=1;
41             }
42         }
43         for(int i=0;i<m;i++)
44         {
45             if(!hasha[i])
46             {
47                 cout<<"No"<<endl;
48                 flag=false;
49                 break;
50             }
51         }
52         if(flag)
53         cout<<"Yes"<<endl;
54     }
55     return 0;
56 }

https://pintia.cn/problem-sets/994805342720868352/exam/problems/994805343043829760

 1 //本题需要注意的点
 2 //这道题要求判断是否是拓扑序列
 3 //那我们就可以依照定义来判断,先入队的是入度为0的节点, 然后将相邻节点的入度减一,再将当前入队的
 4 //的节点出队,再将临界点入度为0的点入队
 5 //而对于本题来讲,在进行加入临界点和入度统计后,我们依次输入给定的节点,如果输入的节点入度不为0
 6 //那他就不是拓扑序列,如果是,就将其临界点的入度也减一,最后判断flag的值
 7 //需要注意输出的格式
 8 #include<bits/stdc++.h>
 9 using namespace std;
10 #define int long long 
11 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
12 const int N=1e3+10;
13 vector<int>g[N];
14 int n,m,k;
15 int tmp;
16 int in[N];
17 bool geshi;
18 signed main()
19 {
20     IOS;
21     cin>>n>>m;
22     int s,t;
23     for(int i=1;i<=m;i++)
24     {
25         cin>>s>>t;
26         g[s].push_back(t);
27         in[t]++;
28         
29     }
30     cin>>k;
31     for(int i=0;i<k;i++)
32     {
33         bool flag=true;
34         vector<int>rd(in,in+1+n);
35         for(int j=0;j<n;j++)
36         {
37             cin>>tmp;
38             if(rd[tmp]!=0)
39             {
40                 flag=false;
41                 //break;
42             }
43             for(int k=0;k<g[tmp].size();k++)
44             {
45                 rd[g[tmp][k]]--;
46             }
47         }
48         if(flag)
49         continue;
50         if(geshi)
51         cout<<" "<<i;
52         else
53         cout<<i;
54         geshi=true;
55     }
56     return 0;
57 }

https://pintia.cn/problem-sets/994805342720868352/exam/problems/1038430013544464384

 1 //题目大意,要求判断给定的序列是否是满足最简TSP图,或者是TSP图,或者不是
 2 //最简TSP就是不仅访问每个点并且首位相连,除此之外还满足k=n+1即访问原点两次
 3 //这道题其实就根据题意判断每个序号的序列是否满足就可以了
 4 //如果这个图有任意两个连续的序列点是不相邻的,那他的距离就是NA
 5 //其余的在输入的时候将其放在集合里,然后判断相邻性和累加距离
 6 //然后判断就可以了
 7 #include<bits/stdc++.h>
 8 using namespace std;
 9 #define int long long
10 #define IOS ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
11 const int INF=0x3f3f3f3f;
12 const int N=210;
13 int g[N][N];
14 int n,m;
15 int q;
16 int index=-1;
17 int ans=INF;
18 void solved(int id)
19 {
20     int sum=0;
21     set<int>s;
22     bool flag=true;
23     int k;
24     vector<int>a(N);
25     cin>>k;
26     for(int i=1;i<=k;i++)
27     {
28         cin>>a[i];
29         s.insert(a[i]);
30     }
31     for(int i=1;i<k;i++)
32     {
33         if(!g[a[i]][a[i+1]])
34             flag=false;
35         sum+=g[a[i]][a[i+1]];
36     }
37     if(!flag)
38     {
39         printf("Path %lld: NA (Not a TS cycle)\n",id);
40         return ;
41     }
42     if(a[1]!=a[k]||s.size()!=n)
43     {
44         printf("Path %lld: %lld (Not a TS cycle)\n",id,sum);
45         return ;
46     }
47     if(k!=n+1)
48     {
49         printf("Path %lld: %lld (TS cycle)\n",id,sum);
50            if(ans>sum)
51         {
52             ans=sum;
53             index=id;
54         }
55     }
56     else{
57        printf("Path %lld: %lld (TS simple cycle)\n",id,sum);
58         if(ans>sum)
59         {
60             ans=sum;
61             index=id;
62         }
63     }
64 }
65 signed main()
66 {
67   //  IOS;
68     cin>>n>>m;
69     int s,t,d;
70     for(int i=1;i<=m;i++)
71     {
72         cin>>s>>t>>d;
73         g[s][t]=g[t][s]=d;
74     }
75     cin>>q;
76     for(int i=1;i<=q;i++)
77     {
78         solved(i);
79     }
80     cout<<"Shortest Dist"<<"("<<index<<")"<<" = "<<ans;
81     return 0;
82 }

 

posted @ 2022-12-02 15:28  江上舟摇  阅读(10)  评论(0编辑  收藏  举报