刷题笔记day8
【PAT A1013】Battle Over Cities
#include<stdio.h> #include<stdlib.h> #include<string.h> const int maxv = 1005; int vis[maxv] = {0}; int g[maxv][maxv]; int ccount; int v;//每次去除的结点 int n,m,k;//城市数、路径数、查询数 void initg() { int i,j; for(i=0;i<maxv;i++) for(j=0;j<maxv;j++) g[i][j] = 0; } void dfs(int nowv) { if(nowv == v) return; vis[nowv] = 1; int i; for(i=1;i<=n;i++) { if(g[nowv][i]==1) { if(vis[i] == 0) { dfs(i); //printf("dfs(%d)\n",i); } } } } void DFSTrave() { int i; for(i=1;i<=n;i++) { if(vis[i] == 0 && i!=v) { ccount++; dfs(i); //printf("dfs(%d)\n",i); } } } int main() { scanf("%d%d%d",&n,&m,&k); int i; for(i=0;i<m;i++) { int a,b; scanf("%d%d",&a,&b); g[a][b] = 1; g[b][a] = 1; } for(i=0;i<k;i++) { memset(vis,0,sizeof(vis)); scanf("%d",&v); ccount = 0; DFSTrave(); printf("%d\n",ccount-1); } }
图的dfs遍历伪代码
//DFS遍历图 //伪代码: DFS(u) { vis[u] = true; for(从u出发能到达的所有顶点v) { if(vis[v] == false) DFS(v); } } DFSTrave(G) { for(G的所有顶点u) { if(vis[u] == false) DFS(u); } }
图的dfs遍历
const int maxv = 1000; const int INF = INT_MAX; //邻接矩阵版 int n,g[maxv][maxv]; bool vis[maxv] = {false}; void DFS(int u,int depth) { vis[u] = true; for(int v=0;v<n;v++) { if(vis[v] == false && g[u][v]!=INF) DFS(v,depth+1); } } void DFSTrave() { for(int u=0;u<n;u++) { if(vis[u] == false) DFS(u,1); } } //邻接表版 vector<int> adj[maxv]; int n; bool vis[maxv] = {false}; void DFS(int u,int depth) { vis[u] = true; for(int i=0;i<adj[u].size();i++) { int v = adj[u][i]; if(vis[v] == false) DFS(v,depth+1); } } void DFSTrave() { for(int u=0;u<n;u++) { if(vis[u] == false) { DFS(u,1); } } }
【PAT A1034】 Head of a Gang
图的遍历。求连通块的总权值。
#include<iostream> #include<map> #include<string> #include<cstdio> using namespace std; const int maxv = 2005; int weight[maxv] = {0}; int g[maxv][maxv]; bool vis[maxv] = {false}; map<string,int> gang; //头目名、人数 map<string,int> string2int; map<int,string> int2string; int numperson = 0; int n,k; int change(string str) { if(string2int.find(str)!=string2int.end()) { return string2int[str]; } else { string2int[str] = numperson; int2string[numperson] = str; return numperson++; } } void dfs(int v,int &head,int &total,int &nummember) { vis[v] = true; nummember++; if(weight[v]>weight[head]) { head = v; } int i; for(i=0;i<numperson;i++) { if(g[v][i]>0) { total += g[v][i]; g[v][i] = g[i][v] = 0; if(vis[i] == false) dfs(i,head,total,nummember); } } } void DFSTrave() { int i; for(i=0;i<numperson;i++) { if(vis[i] == false) { int head = i; int total = 0; int nummember = 0; dfs(i,head,total,nummember); //printf("dfs(%d,%d,%d,%d)\n",i,head,total,nummember); if(total > k && nummember > 2) { gang[int2string[head]] = nummember; } } } } int main() { cin>>n>>k; int i,j; for(i=0;i<maxv;i++) { for(j=0;j<maxv;j++) g[i][j] = 0; } for(i=0;i<n;i++) { string str1,str2; int temp; cin>>str1>>str2>>temp; int id1 = change(str1); int id2 = change(str2); g[id1][id2] += temp; g[id2][id1] += temp; weight[id1] += temp; weight[id2] += temp; } //cout<<numperson<<endl; DFSTrave(); cout<<gang.size()<<endl; map<string,int>::iterator it; for(it = gang.begin();it!=gang.end();it++) { cout<<it->first<<" "<<it->second<<endl; } }
7-8 哈利·波特的考试
弗洛伊德算法——多源最短路
要注意中间节点k要放在循环的最外层。
坑点:二维数组初始赋值最好还是一个一个赋值。
#include<stdio.h> #include<limits.h> #include<stdlib.h> //#define INT_MAX 1000000 int d[105][105]={INT_MAX}; int main() { int n,m; scanf("%d%d",&n,&m); if(n==1) { printf("0\n"); return 0; } int i; int ii; for(i=1;i<=n;i++) for(ii=1;ii<=n;ii++) { if(i==ii) d[i][i] = 0; else d[i][ii] = INT_MAX; } for(i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); scanf("%d",&d[a][b]); d[b][a] = d[a][b]; } int k,j; for(k=1;k<=n;k++) { for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { if(d[i][k]!=INT_MAX && d[k][j]!=INT_MAX && d[i][k]+d[k][j] < d[i][j]) { d[i][j] = d[i][k]+d[k][j] ; } } } } int index = 0; int ans = INT_MAX;//min int mm = 0;//max for(i=1;i<=n;i++) { mm = 0; for(j=1;j<=n;j++) { if(d[i][j]>=mm) { mm = d[i][j]; } } if(mm<ans) { ans = mm; index = i; } } if(index == 0) { printf("0\n"); } else { printf("%d %d\n",index,ans); } }