一本通基础篇图论

Posted iat14

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一本通基础篇图论相关的知识,希望对你有一定的参考价值。

1341 一笔画问题

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <stack>
 4 using namespace std;
 5 const int MAXN = 110000,MAXM = 510000;
 6 stack <int> stk;
 7 int head[MAXN],ind[MAXN];
 8 int to[MAXM],nxt[MAXM],idx[MAXM];
 9 int cnt,n,m;
10 void add(int x,int y,int i)
11 {
12     nxt[++cnt] = head[x];
13     to[cnt] = y;
14     head[x] = cnt;
15     idx[cnt] = i;
16 }
17 void dete(int x,int y)
18 {
19     if (head[x] == y) 
20     {
21         head[x] = nxt[y];
22         return;
23     }
24     for (int i = head[x];i;i = nxt[i])
25         if (nxt[i] == y)
26         {
27             nxt[i] = nxt[y];
28             return;
29         }
30 }
31 void dfs(int x)
32 {
33     for (int i = head[x];i;i = head[x])//注意i=head[x]; 
34     {
35         head[x] = nxt[i];
36         dete(to[i],i ^ 1);
37         dfs(to[i]);
38     }
39     stk.push(x);
40 }
41 int main()
42 {
43     cnt = 1;
44     scanf("%d%d",&n,&m);
45     int ta,tb;
46     for (int i = 1;i <= m;i++)
47     {
48         scanf("%d%d",&ta,&tb);
49         add(ta,tb,i);
50         add(tb,ta,i);
51         ind[ta]++;
52         ind[tb]++;
53     }
54     bool flg = false;
55     for (int i = 1;i <= n;i++)
56         if (ind[i] & 1)
57         {
58             dfs(i);
59             flg = true;
60             break;
61         }
62     if (flg == false)
63         dfs(1);
64     while (!stk.empty())
65     {
66         printf("%d ",stk.top());
67         stk.pop();
68     }
69     return 0;
70 }
View Code

1374 铲雪车

技术图片
 1 #include <cstdio>
 2 #include <cmath>
 3 using namespace std;
 4 typedef long long ll;
 5 int main()
 6 {
 7     ll tx,ty,ux,uy,sx,sy;
 8     scanf("%lld%lld",&sx,&sy);
 9     double ans = 0;
10     while (scanf("%lld%lld%lld%lld",&tx,&ty,&ux,&uy) > 0)
11         ans += sqrt((ux - tx) * (ux - tx) + (uy - ty) * (uy - ty)) * 2;
12     ans = ans / 1000 / 20;
13     ll h = (ll)ans;
14     ll m = (ll)((ans - h) * 60 + 0.5);
15     printf("%lld:%02lld
",h,m);
16     return 0;
17 }
View Code

1375 骑马修栅栏

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <stack>
 4 using namespace std;
 5 stack <int> stk;
 6 int m,n;
 7 int ind[1200],mp[1200][1200];
 8 void dfs(int x)
 9 {
10     for (int i = 1;i <= n;i++)
11         if (mp[x][i])
12         {
13             mp[x][i]--;
14             mp[i][x]--;
15             dfs(i);
16         }
17     stk.push(x);
18 }
19 int main()
20 {
21     scanf("%d",&m);
22     int ta,tb;
23     for (int i = 1;i <= m;i++)
24     {
25         scanf("%d%d",&ta,&tb);
26         n = max(n,ta);
27         n = max(n,tb);
28         mp[ta][tb]++;
29         mp[tb][ta]++; 
30         ind[ta]++;
31         ind[tb]++;
32     }
33     int tp = 1;
34     for (int i = 1;i <= n;i++)
35         if (ind[i] % 2)
36         {
37             tp = i;
38             break;
39         }
40     dfs(tp);
41     while (!stk.empty())
42     {
43         printf("%d
",stk.top());
44         stk.pop();
45     }
46     return 0;
47 }
View Code

1342最短路径问题

 

1343牛的旅行

技术图片
 1 #include <cstdio>
 2 #include <cmath>
 3 #include <algorithm>s 
 4 using namespace std;
 5 double sqr(double x)
 6 {
 7     return x * x; 
 8 }
 9 double mp[200][200],l[200];
10 int x[200],y[200];
11 int n;
12 int main()
13 {
14     scanf("%d",&n);
15     for (int i = 1;i <= n;i++) scanf("%d%d",&x[i],&y[i]);
16     int tmp;
17     for (int i = 1;i <= n;i++)
18         for (int j = 1;j <= n;j++)
19         {
20             scanf("%1d",&tmp);
21             if (tmp == 0 && i != j) mp[i][j] = 2e9;
22             else mp[i][j] = sqrt(sqr(x[i] - x[j]) + sqr(y[i] - y[j])); 
23         }
24     for (int k = 1;k <= n;k++)
25         for (int i = 1;i <= n;i++)
26             for (int j = 1;j <= n;j++)
27                 mp[i][j] = min(mp[i][j],mp[i][k] + mp[k][j]);
28     double res = 2e9,ans = 0;
29     
30     for (int i = 1;i <= n;i++)
31         for (int j = 1;j <= n;j++)
32             if (mp[i][j] < 2e9) l[i] = max(l[i],mp[i][j]);
33     for (int i = 1;i <= n;i++) ans = max(ans,l[i]);
34     for (int i = 1;i <= n;i++)
35         for (int j = 1;j <= n;j++)
36             if (mp[i][j] >= 2e9) res = min(res,l[i] + l[j] + sqrt(sqr(x[i] - x[j]) + sqr(y[i] - y[j])));
37     printf("%.6lf
",max(res,ans));
38     return 0;
39 }
View Code

1344最小花费

技术图片
 1 #include <cstdio>
 2 using namespace std;
 3 double f[2100][2100],dis[2100];
 4 int n,m,s,t;
 5 bool vis[2100];
 6 int main()
 7 {
 8     scanf("%d%d",&n,&m);
 9     int tx,ty;
10     double tz;
11     for (int i = 1;i <= m;i++)
12     {
13         scanf("%d%d%lf",&tx,&ty,&tz);
14         f[tx][ty] = (100.0 - tz) / 100.0;
15         f[ty][tx] = f[tx][ty];
16     }
17     scanf("%d%d",&s,&t);
18     for (int i = 1;i <= n;i++)
19         dis[i] = 0.0;
20     dis[s] = 1.0;
21     for (int i = 2;i <= n;i++)
22     {
23         double maxn = 0.0;
24         int loc = 0;
25         for (int j = 1;j <= n;j++)
26              if (!vis[j] && dis[j] > maxn)
27              {
28                  maxn = dis[j]; 
29                 loc = j;
30             }
31         if (loc == 0) 
32             break;
33         vis[loc] = true;
34         for (int j = 1;j <= n;j++)
35                if (!vis[j] && dis[loc] * f[loc][j] > dis[j])
36                  dis[j] = dis[loc] * f[loc][j];
37     } 
38     printf("%.8lf",100.0 / dis[t]);
39     return 0;
40 }
View Code

1345香甜的黄油

技术图片
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<queue>
 4 using namespace std;
 5 const int MAXN = 810,MAXM = 3100,inf = 1000000000;
 6 int head[MAXN],dis[MAXN],to[MAXM],val[MAXM],nxt[MAXM],s[MAXN],cnt,c,n,m,ans;
 7 bool vis[MAXN];
 8 struct pot
 9 {
10     int x,dis;
11     pot (int _x = 0,int _dis = 0) : x(_x),dis(_dis) {}
12     friend bool operator < (pot a,pot b)
13     {
14         return a.dis > b.dis;
15     }
16 };
17 priority_queue <pot> que;
18 void add(int x,int y,int v)
19 {
20     nxt[++cnt] = head[x];
21     to[cnt] = y;
22     head[x] = cnt;
23     val[cnt] = v;
24 }
25 void dijkstra(int sta)
26 {
27     for (int i = 1; i <= n;i++) 
28         dis[i] = inf;
29     for (int i = 1;i <= n;i++)
30         vis[i] = false;
31     que.push(pot(sta,0));
32     dis[sta] = 0;
33     while (!que.empty())
34     {
35         pot now = que.top();
36         que.pop();
37         if (vis[now.x]) 
38             continue;
39         vis[now.x] = true;
40         for (int i = head[now.x];i;i = nxt[i])
41         {
42             if (dis[to[i]] > dis[now.x] + val[i])
43             {
44                 dis[to[i]] = dis[now.x] + val[i];
45                 que.push(pot(to[i],dis[to[i]]));
46             }
47         }
48     }
49 }
50 int main()
51 {    
52     scanf("%d%d%d",&c,&n,&m);
53     for (int i = 1;i <= c;i++)
54         scanf("%d",&s[i]);
55     int tu,tv,tw;
56     for (int i = 1;i <= m;i++)
57     {
58         scanf("%d%d%d",&tu,&tv,&tw);
59         add(tu,tv,tw);
60         add(tv,tu,tw);
61     }
62     ans = inf;
63     for (int i = 1;i <= n;i++)
64     {
65         int sum = 0;
66         dijkstra(i);
67         for (int j = 1;j <= c;j++)
68             sum += dis[s[j]];
69         ans = min(ans,sum);
70     }
71     printf("%d
",ans);
72     return 0;
73 }
View Code

1376信使

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 const int MAXN = 110,MAXM = 11000;
 7 int head[MAXN],dis[MAXN],vis[MAXN],to[MAXM],nxt[MAXM],val[MAXM];
 8 bool inq[MAXN];
 9 int n,m,cnt;
10 void add(int x,int y,int v)
11 {
12     nxt[++cnt] = head[x];
13     to[cnt] = y;
14     head[x] = cnt;
15     val[cnt] = v;
16 }
17 bool SPFA(int s)
18 {
19     dis[s] = 0;
20     vis[s] = 1;
21     queue<int> q;
22     q.push(s);
23     inq[s] = true;
24     while(!q.empty())
25     {
26         int t = q.front();
27         q.pop();
28         inq[t] = false;
29         for(int i = head[t];i;i = nxt[i])
30         {
31             if(dis[to[i]] > dis[t] + val[i])
32             {
33                 dis[to[i]] = dis[t] + val[i];
34                 if(!inq[to[i]])
35                 {
36                     inq[to[i]] = 1;
37                     vis[to[i]]++;
38                     if(vis[to[i]] >= n) return true;
39                     q.push(to[i]);
40                 }
41             }
42         }
43     }
44     return false;
45 }
46 int main()
47 {
48     memset(dis,0x1f,sizeof(dis));
49     scanf("%d%d",&n,&m);
50     int tx,ty,tv;
51     for (int i = 1;i <= m;i++)
52     {
53         scanf("%d%d%d",&tx,&ty,&tv);
54         add(tx,ty,tv);
55         add(ty,tx,tv);
56     }
57     SPFA(1);
58     int maxn = 0;
59     for (int i = 1;i <= n;i++)
60         maxn = max(maxn,dis[i]);
61     if (maxn == dis[0])
62         printf("-1
");
63     else 
64         printf("%d
",maxn);
65     return 0;
66 }
View Code

1377最优乘车

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 int mp[510][510],vec[510],n,m;
 6 char str[5100];
 7 int main()
 8 {
 9     scanf("%d%d",&m,&n);
10     gets(str);
11     memset(mp,0x1f,sizeof(mp));
12     for (int i = 1;i <= m;i++)
13     {
14         gets(str);
15         int tmp = 0,cnt = 0; 
16         for (int i = 0;str[i] != 0;i++)
17             if (str[i] >= 0 && str[i] <= 9)
18                 tmp = tmp * 10 + str[i] - 0;
19             else if (str[i] ==  )
20             {
21                 vec[++cnt] = tmp;
22                 tmp = 0;
23             }
24         if (tmp != 0)
25             vec[++cnt] = tmp;
26         for(int j = 1;j <= cnt;j++)
27             for(int k = j + 1;k <= cnt;k++)
28                 mp[vec[j]][vec[k]] = 1;
29     }
30     for (int k = 1;k <= n;k++)
31         for (int i = 1;i <= n;i++)
32             for (int j = 1;j <= n;j++)
33                 mp[i][j] = min(mp[i][j],mp[i][k] + mp[k][j]);
34 //    for (int i = 1;i <= n;i++,printf("
"))
35 //        for (int j = 1;j <= n;j++)
36 //            printf("%d ",mp[i][j]);
37     if (mp[1][n] >= 100000) 
38         printf("NO");
39     else 
40         printf("%d
",mp[1][n] - 1);
41     return 0;
42 }
View Code

1378最短路径

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 const int MAXN = 110;
 7 int dis[MAXN],vis[MAXN],mp[MAXN][MAXN];
 8 bool inq[MAXN];
 9 int n,s;
10 bool SPFA(int s)
11 {
12     dis[s] = 0;
13     vis[s] = 1;
14     queue<int> q;
15     q.push(s);
16     inq[s] = true;
17     while(!q.empty())
18     {
19         int t = q.front();
20         q.pop();
21         inq[t] = false;
22         for (int i = 1;i <= n;i++)
23         {
24             if(dis[i] > dis[t] + mp[t][i])
25             {
26                 dis[i] = dis[t] + mp[t][i];
27                 if(!inq[i])
28                 {
29                     inq[i] = 1;
30                     vis[i]++;
31                     if(vis[i] >= n) return true;
32                     q.push(i);
33                 }
34             }
35         }
36     }
37     return false;
38 }
39 int solve(char * str)
40 {
41     int ans = 0,f = 1;
42     if (str[0] == - && str[1] == 0)
43         return dis[0];
44     if (str[0] == -)
45         f = -1;
46     for (int i = (f == 1 ? 0 : 1);str[i] != 0;i++)
47         ans = ans * 10 + str[i] - 0;
48     return ans * f;
49 }
50 int main()
51 {
52     memset(dis,0x1f,sizeof(dis));
53     memset(mp,0x1f,sizeof(mp));
54     scanf("%d%d",&n,&s);
55     int tx,ty,tv;
56     char str[10];
57     for (int i = 1;i <= n;i++)
58         for (int j = 1;j <= n;j++)
59         {
60             scanf("%s",str);
61             mp[i][j] = solve(str);
62         }
63     SPFA(s);
64     for (int i = 1;i <= n;i++)
65         if (i != s)
66             printf("(%d -> %d) = %d
",s,i,dis[i]);
67     return 0;
68 }
View Code

1379热浪

技术图片
 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring> 
 4 using namespace std;
 5 const int MAXN = 3000,MAXM = 14000;
 6 struct pot
 7 {
 8     int x,dis;
 9     pot(int _x = 0,int _dis = 0) :x(_x),dis(_dis){}
10     friend bool operator < (pot a,pot b)
11     {
12         return a.dis > b.dis;
13     }
14 };
15 priority_queue <pot> que;
16 bool vis[MAXN];
17 int head[MAXN],dis[MAXN];
18 int to[MAXM],nxt[MAXM],val[MAXM];
19 int cnt,n,m,s,t;
20 void add(int x,int y,int v)
21 {
22     nxt[++cnt] = head[x];
23     to[cnt] = y;
24     val[cnt] = v;
25     head[x] = cnt;
26 }
27 void dij(int s)
28 {
29     while (!que.empty()) que.pop();
30     que.push(pot(s,0));
31     memset(dis,0x1f,sizeof(dis));
32     dis[s] = 0;
33     while (!que.empty())
34     {
35         int u = que.top().x;
36         que.pop();
37         if (vis[u]) continue;
38         vis[u] = true;
39         for (int i = head[u];i;i = nxt[i])
40         {
41             if (dis[to[i]] > dis[u] + val[i])
42             {
43                 dis[to[i]] = dis[u] + val[i];
44                 que.push(pot(to[i],dis[to[i]]));
45             }
46         }
47     }
48 }
49 int main()
50 {
51     scanf("%d%d%d%d",&n,&m,&s,&t);
52     int tx,ty,tv;
53     for (int i = 1;i <= m;i++)
54     {
55         scanf("%d%d%d",&tx,&ty,&tv);
56         add(tx,ty,tv);
57         add(ty,tx,tv); 
58     }
59     dij(s);
60     printf("%d
",dis[t]);
61     return 0;
62 }
View Code

1380分糖果

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 const int MAXN = 110000,MAXM = 2100000;
 7 int head[MAXN],dis[MAXN],to[MAXM],nxt[MAXM];
 8 int n,m,p,c,cnt;
 9 void add(int x,int y)
10 {
11     nxt[++cnt] = head[x];
12     to[cnt] = y;
13     head[x] = cnt;
14 }
15 bool BFS(int s)
16 {
17     dis[s] = 1;
18     queue<int> q;
19     q.push(s);
20     while(!q.empty())
21     {
22         int t = q.front();
23         q.pop();
24         for(int i = head[t];i;i = nxt[i])
25         {
26             if(dis[to[i]] == -1)
27             {
28                 dis[to[i]] = dis[t] + 1;
29                 q.push(to[i]);
30             }
31         }
32     }
33     return false;
34 }
35 int main()
36 {
37     memset(dis,-1,sizeof(dis));
38     scanf("%d%d%d%d",&n,&p,&c,&m);
39     int tx,ty;
40     for (int i = 1;i <= p;i++)
41     {
42         scanf("%d%d",&tx,&ty);
43         add(tx,ty);
44         add(ty,tx);
45     }
46     BFS(c);
47     int maxn = 0;
48     for (int i = 1;i <= n;i++)
49         maxn = max(maxn,dis[i]);
50     printf("%d
",maxn + m);
51     return 0;
52 }
View Code

1381城市路

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 const int MAXN = 2100,MAXM = 21000;
 7 int head[MAXN],dis[MAXN],vis[MAXN],to[MAXM],nxt[MAXM],val[MAXM];
 8 bool inq[MAXN];
 9 int n,m,cnt;
10 void add(int x,int y,int v)
11 {
12     nxt[++cnt] = head[x];
13     to[cnt] = y;
14     head[x] = cnt;
15     val[cnt] = v;
16 }
17 bool SPFA(int s)
18 {
19     dis[s] = 0;
20     vis[s] = 1;
21     queue<int> q;
22     q.push(s);
23     inq[s] = true;
24     while(!q.empty())
25     {
26         int t = q.front();
27         q.pop();
28         inq[t] = false;
29         for(int i = head[t];i;i = nxt[i])
30         {
31             if(dis[to[i]] > dis[t] + val[i])
32             {
33                 dis[to[i]] = dis[t] + val[i];
34                 if(!inq[to[i]])
35                 {
36                     inq[to[i]] = 1;
37                     vis[to[i]]++;
38                     if(vis[to[i]] >= n) return true;
39                     q.push(to[i]);
40                 }
41             }
42         }
43     }
44     return false;
45 }
46 int main()
47 {
48     memset(dis,0x1f,sizeof(dis));
49     scanf("%d%d",&n,&m);
50     int tx,ty,tv;
51     for (int i = 1;i <= m;i++)
52     {
53         scanf("%d%d%d",&tx,&ty,&tv);
54         add(tx,ty,tv);
55         add(ty,tx,tv);
56     }
57     SPFA(1);
58     if (dis[n] == dis[0])
59         printf("-1
");
60     else
61         printf("%d
",dis[n]);
62     return 0;
63 }
View Code

1382最短路 

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 const int MAXN = 110000,MAXM = 1100000;
 7 int head[MAXN],dis[MAXN],vis[MAXN],to[MAXM],nxt[MAXM],val[MAXM];
 8 bool inq[MAXN];
 9 int n,m,cnt;
10 void add(int x,int y,int v)
11 {
12     nxt[++cnt] = head[x];
13     to[cnt] = y;
14     head[x] = cnt;
15     val[cnt] = v;
16 }
17 bool SPFA(int s)
18 {
19     dis[s] = 0;
20     vis[s] = 1;
21     queue<int> q;
22     q.push(s);
23     inq[s] = true;
24     while(!q.empty())
25     {
26         int t = q.front();
27         q.pop();
28         inq[t] = false;
29         for(int i = head[t];i;i = nxt[i])
30         {
31             if(dis[to[i]] > dis[t] + val[i])
32             {
33                 dis[to[i]] = dis[t] + val[i];
34                 if(!inq[to[i]])
35                 {
36                     inq[to[i]] = 1;
37                     vis[to[i]]++;
38                     if(vis[to[i]] >= n) return true;
39                     q.push(to[i]);
40                 }
41             }
42         }
43     }
44     return false;
45 }
46 int main()
47 {
48     memset(dis,0x1f,sizeof(dis));
49     scanf("%d%d",&n,&m);
50     int tx,ty,tv;
51     for (int i = 1;i <= m;i++)
52     {
53         scanf("%d%d%d",&tx,&ty,&tv);
54         add(tx,ty,tv);
55         add(ty,tx,tv);
56     }
57     SPFA(1);
58     printf("%d
",dis[n]);
59     return 0;
60 }
View Code

1383刻录光盘

技术图片
 1 #include <cstdio>
 2 #include <stack>
 3 using namespace std;
 4 const int MAXN = 210,MAXM = 41000;
 5 int head[MAXN],dfn[MAXN],low[MAXN],nxt[MAXM],to[MAXM],blg[MAXN],ind[MAXN];
 6 bool ins[MAXN];
 7 int cnt,n,tim,scc,ans;
 8 stack <int> stk;
 9 void add(int x,int y)
10 {
11     nxt[++cnt] = head[x];
12     to[cnt] = y;
13     head[x] = cnt;
14 }
15 void tarjan(int x)
16 {
17     dfn[x] = low[x] = ++tim;
18     stk.push(x); 
19     ins[x] = true;
20     for (int i = head[x];i;i = nxt[i])
21     {
22         if (!dfn[to[i]])
23         {
24             tarjan(to[i]);
25             low[x] = min(low[x],low[to[i]]);
26         }else if (ins[to[i]]) 
27             low[x] = min(low[x],dfn[to[i]]);
28     }
29     if (low[x] == dfn[x])
30     {
31         ++scc;
32         int tmp = 0;
33         while (tmp != x)
34         {
35             tmp = stk.top();
36             stk.pop();
37             ins[tmp] = false;
38             blg[tmp] = scc;
39         }
40     }
41 }
42 int main()
43 {
44     scanf("%d",&n);
45     for (int i = 1;i <= n;i++)
46     {
47         int tx = 1;
48         for (;;)
49         {
50             scanf("%d",&tx);
51             if (tx == 0)
52                 break;
53             add(i,tx);
54         }
55     }
56     for (int i = 1;i <= n;i++)
57         if (dfn[i] == 0)
58             tarjan(i);
59     for (int i = 1;i <= n;i++)
60         for (int o = head[i];o;o = nxt[o])
61             if (blg[i] != blg[to[o]])
62                 ind[blg[to[o]]]++;
63     for (int i = 1;i <= scc;i++)
64         if (ind[i] == 0)
65             ans++;
66     printf("%d
",ans);
67 }
View Code

1384珍珠

技术图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN = 200;
 4 int a[MAXN][MAXN],b[MAXN][MAXN],cnt1[MAXN],cnt2[MAXN],n,m;
 5 int main()
 6 {
 7     scanf("%d%d",&n,&m);
 8     int tx,ty;
 9     for (int i = 1;i <= m;i++)
10     {
11         scanf("%d%d",&tx,&ty);
12         a[tx][ty] = 1;
13         b[ty][tx] = 1;
14     }
15     for (int k = 1;k <= n;k++)
16         for (int i = 1;i <= n;i++)
17             for (int j = 1;j <= n;j++)
18                 if (k != i && k != j && i != j)
19                 {
20                     a[i][j] |= a[i][k] && a[k][j];
21                     b[i][j] |= b[i][k] && b[k][j];
22                 }
23     for (int i = 1;i <= n;i++)
24         for (int j = 1;j <= n;j++)
25             if (i != j){
26                 if (a[i][j]) cnt1[i]++;
27                 if (b[i][j]) cnt2[i]++;
28             }
29     int ans=0;
30     for (int i=1;i<=n;i++)
31         if (cnt1[i] >= (n + 1) / 2 || cnt2[i] >= (n + 1) / 2) 
32             ans++;
33     printf("%d
",ans);
34     return 0;
35 }
View Code

1346亲戚

技术图片
 1 #include <cstdio>
 2 using namespace std;
 3 int fa[21000],siz[21000]; 
 4 int n,m,q;
 5 int read()
 6 {
 7     int x=0,f=1;char ch=getchar();
 8     while(ch<0||ch>9){if(ch==-)f=-1;ch=getchar();}
 9     while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
10     return x*f;
11 }
12 void pre_dsu(int n)
13 {
14     for (int i = 1;i <= n;i++) 
15         fa[i] = i,siz[i] = 1;
16 }
17 int getfa(int u)
18 {
19     if (fa[u] == u) return u;
20     return fa[u] = getfa(fa[u]);
21 }
22 void merge(int u,int v)
23 {
24     int s1 = getfa(u),s2 = getfa(v);
25     if(s1 == s2) return;
26     if (siz[s1] < siz[s2])
27     {
28         fa[s1] = s2;
29     }else if (siz[s1] > siz[s2])
30     {
31         fa[s2] = s1;
32     }else 
33     {
34         fa[s1] = s2;
35         siz[s1]++;
36     }
37 }
38 int main()
39 {
40     scanf("%d%d",&n,&m);
41     pre_dsu(n);
42     int ta,tb;
43     for (int i = 1;i <= m;i++)
44     {
45         ta = read();
46         tb = read();
47         if(getfa(ta) != getfa(tb))
48             merge(ta,tb);
49     }
50     scanf("%d",&q);
51     for (int i = 1;i <= q;i++)
52     {
53         ta = read();
54         tb = read();
55         if (getfa(ta) == getfa(tb))
56             printf("Yes
");
57         else
58             printf("No
");
59     }
60     return 0;
61 }
View Code

1347格子游戏

技术图片
 1 #include <cstdio>
 2 using namespace std;
 3 int fa[41000],siz[41000]; 
 4 int n,m;
 5 void pre_dsu(int n)
 6 {
 7     for (int i = 1;i <= n;i++) 
 8         fa[i] = i,siz[i] = 1;
 9 }
10 int getfa(int u)
11 {
12     if (fa[u] == u) return u;
13     return fa[u] = getfa(fa[u]);
14 }
15 void merge(int u,int v)
16 {
17     int s1 = getfa(u),s2 = getfa(v);
18     if(s1 == s2) return;
19     if (siz[s1] < siz[s2])
20     {
21         fa[s1] = s2;
22         siz[s2] += siz[s1];
23     }else
24     {
25         fa[s2] = s1;
26         siz[s1] += siz[s2];
27     }
28 }
29 int num(int x,int y)
30 {
31     return (x - 1) * n + y;
32 }
33 int main()
34 {
35     scanf("%d%d",&n,&m);
36     pre_dsu(n * n);
37     int tx,ty,ta,tb;
38     char s[10]; 
39     for (int i = 1;i <= m;i++)
40     {
41         scanf("%d%d%s",&tx,&ty,s);
42         ta = num(tx,ty);
43         if (s[0] == D)
44             tb = num(tx + 1,ty);
45         else
46             tb = num(tx,ty + 1);
47         if (getfa(ta) == getfa(tb))
48         {
49             printf("%d
",i);
50             return 0;
51         }
52         merge(ta,tb);
53     }
54     printf("draw
");
55     return 0;
56 }
View Code

1385团伙

技术图片
 1 #include <cstdio>
 2 using namespace std;
 3 int fa[2100],siz[2100]; 
 4 bool vis[2100];
 5 int n,m,cnt;
 6 void pre_dsu(int n)
 7 {
 8     for (int i = 1;i <= n;i++) 
 9         fa[i] = i,siz[i] = 1;
10 }
11 int getfa(int u)
12 {
13     if (fa[u] == u) return u;
14     return fa[u] = getfa(fa[u]);
15 }
16 void merge(int u,int v)
17 {
18     int s1 = getfa(u),s2 = getfa(v);
19     if(s1 == s2) return;
20     if (siz[s1] < siz[s2])
21     {
22         fa[s1] = s2;
23         siz[s2] += siz[s1];
24     }else
25     {
26         fa[s2] = s1;
27         siz[s1] += siz[s2];
28     }
29 }
30 int main()
31 {
32     scanf("%d%d",&n,&m);
33     pre_dsu(2 * n);
34     int tp,tx,ty;
35     for (int i = 1;i <= m;i++)
36     {
37         scanf("%d%d%d",&tp,&tx,&ty);
38         if (tp == 0)
39         {
40             merge(tx,ty);
41         }else
42         {
43             merge(tx,ty + n);
44             merge(tx + n,ty);
45         }
46     }
47     for (int i = 1;i <= n;i++)
48         if (vis[getfa(i)] == false)
49         {
50             vis[getfa(i)] = true;
51             cnt++;
52         }
53     printf("%d
",cnt);
54     return 0;
55 }
View Code

1386打击犯罪

技术图片
 1 #include <cstdio>
 2 using namespace std;
 3 int fa[1100],siz[1100]; 
 4 int n,m,cnt,a[1100][1100];
 5 void pre_dsu(int n)
 6 {
 7     for (int i = 1;i <= n;i++) 
 8         fa[i] = i,siz[i] = 1;
 9 }
10 int getfa(int u)
11 {
12     if (fa[u] == u) return u;
13     return fa[u] = getfa(fa[u]);
14 }
15 void merge(int u,int v)
16 {
17     int s1 = getfa(u),s2 = getfa(v);
18     if(s1 == s2) return;
19     if (siz[s1] < siz[s2])
20     {
21         fa[s1] = s2;
22         siz[s2] += siz[s1];
23     }else
24     {
25         fa[s2] = s1;
26         siz[s1] += siz[s2];
27     }
28 }
29 int main()
30 {
31     scanf("%d",&n);
32     pre_dsu(n);
33     for (int i = 1;i <= n;i++)
34     {
35         scanf("%d",&a[i][0]);
36         for (int j = 1;j <= a[i][0];j++)
37             scanf("%d",&a[i][j]);
38     }
39     for (int i = n;i >= 1;i--)
40     {
41         for (int j = 1;j <= a[i][0];j++)
42             if(a[i][j] > i)
43             {
44                 merge(i,a[i][j]);
45                 if (siz[getfa(i)] > n / 2 || siz[getfa(a[i][j])] > n / 2)
46                 {
47                     printf("%d
",i);
48                     return 0;
49                 }
50             }
51     }
52 }
View Code

1387搭配购买

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 int fa[11000],siz[11000],f[11000],c[11000],d[11000],cst[11000],val[11000]; 
 5 int n,m,w,cnt,ans;
 6 void pre_dsu(int n)
 7 {
 8     for (int i = 1;i <= n;i++) 
 9         fa[i] = i,siz[i] = 1;
10 }
11 int getfa(int u)
12 {
13     if (fa[u] == u) return u;
14     return fa[u] = getfa(fa[u]);
15 }
16 void merge(int u,int v)
17 {
18     int s1 = getfa(u),s2 = getfa(v);
19     if(s1 == s2) return;
20     if (siz[s1] < siz[s2])
21     {
22         fa[s1] = s2;
23         siz[s2] += siz[s1];
24         c[s2] += c[s1];
25         d[s2] += d[s1];
26     }else
27     {
28         fa[s2] = s1;
29         siz[s1] += siz[s2];
30         c[s1] += c[s2];
31         d[s1] += d[s2];
32     }
33 }
34 int main()
35 {
36     scanf("%d%d%d",&n,&m,&w);
37     pre_dsu(n); 
38     for (int i = 1;i <= n;i++)
39         scanf("%d%d",&c[i],&d[i]);
40     int ta,tb;
41     for (int i = 1;i <= m;i++)
42     {
43         scanf("%d%d",&ta,&tb);
44         merge(ta,tb); 
45     }
46     for (int i = 1;i <= n;i++)
47         if (fa[i] == i)
48         {
49             cnt++;
50             cst[cnt] = c[i];
51             val[cnt] = d[i];
52         }
53     for (int i = 1;i <= cnt;i++)
54         for (int j = w;j >= cst[i];j--)
55             f[j] = max(f[j],f[j - cst[i]] + val[i]);
56     for (int i = 0;i <= w;i++)
57         ans = max(ans,f[i]); 
58     printf("%d
",ans);
59 }
View Code

1388家谱

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <string>
 4 #include <map>
 5 #include <iostream>
 6 using namespace std;
 7 map <string,int> mp;
 8 int fa[51000]; 
 9 int cnt;
10 string nam[51000];
11 void pre_dsu(int n)
12 {
13     for (int i = 1;i <= n;i++) 
14         fa[i] = i;
15 }
16 int getfa(int u)
17 {
18     if (fa[u] == u) return u;
19     return fa[u] = getfa(fa[u]);
20 }
21 int main()
22 {
23     pre_dsu(50000);
24     string s;
25     int f;
26     for (;;)
27     {
28         cin >> s;
29         if (mp[s.substr(1)] == 0)
30         {
31             mp[s.substr(1)] = ++cnt;
32             nam[cnt] = s.substr(1);
33         }
34         if (s[0] == #)
35         {
36             f = mp[s.substr(1)];
37         }else if (s[0] == +)
38         {
39             fa[mp[s.substr(1)]] = f;
40         }else if (s[0] == ?)
41         {
42             cout << s.substr(1) << " " << nam[getfa(mp[s.substr(1)])] << endl;
43         }else
44         {
45             return 0;
46         }
47     } 
48 }
View Code

1389亲戚

技术图片
 1 #include <cstdio>
 2 using namespace std;
 3 int fa[110000],siz[110000]; 
 4 int n,m;
 5 void pre_dsu(int n)
 6 {
 7     for (int i = 1;i <= n;i++) 
 8         fa[i] = i,siz[i] = 1;
 9 }
10 int getfa(int u)
11 {
12     if (fa[u] == u) return u;
13     return fa[u] = getfa(fa[u]);
14 }
15 void merge(int u,int v)
16 {
17     int s1 = getfa(u),s2 = getfa(v);
18     if(s1 == s2) return;
19     if (siz[s1] < siz[s2])
20     {
21         fa[s1] = s2;
22         siz[s2] += siz[s1];
23     }else
24     {
25         fa[s2] = s1;
26         siz[s1] += siz[s2];
27     }
28 }
29 int main()
30 {
31     scanf("%d%d",&n,&m);
32     pre_dsu(n);
33     int ta,tb;
34     char s[10];
35     for (int i = 1;i <= m;i++)
36     {
37         scanf("%s",s);
38         if (s[0] == M)
39         {
40             scanf("%d%d",&ta,&tb);
41             merge(ta,tb);
42         }else
43         {
44             scanf("%d",&ta);
45             printf("%d
",siz[getfa(ta)]);
46         }
47     }
48     return 0;
49 }
View Code

1390食物链

比较难,带权并查集,可以忽略。

技术图片
 1 #include <cstdio>
 2 using namespace std;
 3 int fa[51000],num[51000]; 
 4 int n,k,cnt;
 5 void pre_dsu(int n)
 6 {
 7     for (int i = 1;i <= n;i++) 
 8         fa[i] = i;
 9 }
10 int getfa(int u)
11 {
12     if (fa[u] == u) return u;
13     int f = fa[u];
14     fa[u] = getfa(fa[u]);
15     num[u] = (num[f] + num[u]) % 3;
16     return fa[u];
17 }
18 int main()
19 {
20     scanf("%d%d",&n,&k);
21     pre_dsu(n);
22     int td,tx,ty,ta,tb;
23     for (int i = 1;i <= k;i++)
24     {
25         scanf("%d%d%d",&td,&tx,&ty);
26         if (tx > n || ty > n)
27         {
28             cnt++;
29             continue;
30         }
31         ta = getfa(tx);
32         tb = getfa(ty);
33         if (ta == tb)
34         {
35             if (td == 1 && num[tx] != num[ty])
36             {
37                 cnt++;
38                 continue;
39             }else if (td == 2 && num[tx] != (num[ty] + 1) % 3)
40             {
41                 cnt++;
42                 continue;
43             }
44         }else
45         {
46             if (td == 1)
47             {
48                 fa[ta] = tb;
49                 num[ta] = (3 + num[ty] - num[tx]) % 3;
50             }else
51             {
52                 fa[ta] = tb;
53                 num[ta] = (3 + num[ty] - num[tx] + 1) % 3;
54             }
55         }
56     }
57     printf("%d
",cnt);
58     return 0;
59 }
View Code

1348城市公交网建设问题

1349最优布线问题

1350最短网络

1351家谱树

1391局域网

1392繁忙的都市

1393联络员

1394连接格点

1352奖金

1395烦人的幻灯片

1396病毒

以上是关于一本通基础篇图论的主要内容,如果未能解决你的问题,请参考以下文章

信息学奥赛一本通 1341:例题一笔画问题

信息学奥赛一本通 1384:珍珠(bead)

图论算法

《信息学奥赛一本通》题库 1034 计算三角形面积——基础

信息学奥赛一本通Part1.2 基础算法-二分与三分

信息学奥赛一本通Part6.1 数学基础-快速幂