校園網絡
1
5
2 4 3 0
4 5 0
0
0
1 0
樣例輸出
2
#include
#include
#include
#include
#define maxn 102
using namespace std;
vector G[maxn],G2[maxn];
vector s;//棧
int vis[maxn],
sccno[maxn], //標記頂點所屬的連通分量
scc_cnt; //記錄有幾個強連通分量
void dfs1(int u)
{
if(vis[u]) return ; //頂點遍歷過則返回
vis[u] = 1;
for(int i=0; i=0; i--)if( !sccno[s[i]] ){//找強連通分量,找過了則不用找了
scc_cnt++; //記錄找到連通分量的個數
dfs2(s[i]);
}
}
int main()
{
//freopen("in.txt","r",stdin);
int i,j,T,n,u,ver;
int in0[maxn],out0[maxn];
cin>>T;
while(T--)
{
cin>>n;
for(i=1; i<=n; i++)
for(j=1; j<=n; j++){
cin>>ver;
if(ver==0)break;
G[i-1].push_back(ver-1); //原圖
G2[ver-1].push_back(i-1);//逆向圖
}
find_scc(n); //求連通分量
for(i=1; i<=scc_cnt; i++)in0[i] = out0[i] = 1;//同一個連通分量所有點看成一個點
for(u=0; u
#include
#include
using namespace std;
int m;
bool map[110][110];
bool instack[110];
bool used[110];
bool income[110];
bool outcome[110];
int color[110];
int color_num;
int nodeNum[110];
int low[110];
int num;
stack Stack;
void dfs(int node)
{
used[node] = 1;
nodeNum[node] = ++num;
low[node] = num;
Stack.push(node);
instack[node] = 1;
int i;
for(i = 1; i <= m; i++)
{
if(map[node][i] == 1)
{
if(used[i] == 1)
{
if(instack[i] == 1)
{
low[node] = low[node] > low[i] ? low[i] : low[node];
}
}
else
{
dfs(i);
low[node] = low[node] > low[i] ? low[i] : low[node];
}
}
}
if(low[node] == nodeNum[node])
{
while(!Stack.empty())
{
int top = Stack.top();
Stack.pop();
instack[top] = 0;
color[top] = color_num;
if(top == node)
{
color_num++;
break;
}
}
}
}
void tarjan(int * in, int * out)
{
int i;
for(i = 0; i <= m; i++)
{
instack[i] = 0;
used[i] = 0;
income[i] = 0;
outcome[i] = 0;
color[i] = 0;
nodeNum[i] = 0;
low[i] = 0;
}
color_num = 1;
num = 0;
for(i = 1; i <= m; i++)
{
if(used[i] == 0)
{
dfs(i);
}
}
int j;
for(i = 1; i <= m; i++)
{
for(j = 1; j <= m; j++)
{
if(map[i][j])
{
if(color[i] != color[j])
{
income[color[j]] ++;
outcome[color[i]]++;
}
}
}
}
int flag_in = 0;
int flag_out = 0;
for(i = 1; i < color_num; i++)
{
if(income[i] == 0)
flag_in ++;
if(outcome[i] == 0)
flag_out++;
}
*in = flag_in;
*out = flag_out;
}
int main()
{
// freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
while(t--)
{
memset(map, 0, sizeof(map));
scanf("%d", &m);
int i;
int ai;
for(i = 1; i <= m; i++)
{
while(scanf("%d", &ai), ai != 0)
{
map[i][ai] = 1;
}
}
int in, out;
tarjan(&in, &out);
if(in == 1 && out == 1)
printf("0\n");
else
printf("%d\n", in > out? in : out);
}
return 0;
}
1組數
6點 8條線
1 6 8 1 2 1 3 2 4 2 5 3 4 3 6 4 6 5 6輸出
最多3個黑點
編號分別爲 1 4 5
#include
#include
int max,n,color[101],black[101],map[101][101];
int dfs(int x,int num)
{int i,f=1;
if (max
#include
#include
#define NMAX 110
bool path[NMAX][NMAX];
int n, mmax;
int dp[NMAX];
bool v[NMAX];
int seq[NMAX], seq_pos;
//seq記錄最大團集合
bool dfs(int pos, int size)
{
int i, j, unvis;
bool tv[NMAX];
unvis = 0;
for (i=pos; i mmax)
{
mmax = size;
seq_pos = 0;
seq[ seq_pos ++] = pos+1;
return true;
}
return false;
}
for (i=pos; i < n && unvis > 0 ; i++)
{
if (!v[i])
{
if (unvis + size <= mmax || dp[i] + size <= mmax)
{
return false;
}
v[i] = true;//U = U\{vi}
unvis --;
memcpy(tv, v, sizeof(v));
for (j=0; j=0; i--)
{
for (j=0; j
The Perfect Stall
5 5
2 1 5
3 1 2 5
1 2
Sample Output
4
#include
using namespace std;
int n,m,match[300]; //二分圖的兩個集合分別含有n和m個節點
bool visit[300],map[210][210]; //map存儲圖G的鄰接矩陣
bool dfs(int k)
{
int t;
for(int i=1;i<=m;i++)
if(map[k][i] && !visit[i]) //如果節點i與k相鄰並且未被查找過
{
visit[i]=true; //標記i爲已查找過
if(match[i]==-1 //如果i未在前一個匹配M中
|| dfs(match[i])) //i在匹配M中,但是從與i相鄰的節點出發可以有增廣路
{
match[i]=k; //記錄查找成功記錄
return true;
}
}
return false;
}
int main()
{
int p,q,r,i,j;
while(cin>>n>>m)
{
memset(map,0,sizeof(map));
int s=0;
for( i=1;i<=n;i++)
{
cin>>p;
for(j=1;j<=p;j++)
{
cin>>q;
map[i][q]=1;
}
}
memset(match,-1,sizeof(match));
for( i=1;i<=n;i++) //以二分集中的較小集n進行匹配較優
{
memset(visit,false,sizeof(visit));
if (dfs(i)) s++; //s爲匹配數
}
cout<
#include
#include
using namespace std;
const int maxn=210;
int map[maxn][maxn];
int vis[maxn];
int match[maxn];
int n,m;
int dfs(int x)
{
int i;
for(int i=1;i<=m;i++)
{
if(vis[i]==-1&&map[x][i])
{
vis[i]=1;
if(match[i]==-1||dfs(match[i]))
{
match[i]=x;
return 1;
}
}
}
return 0;
}
int maxmatch()
{
int i,sum=0;
for(i=1;i<=n;i++)
{
memset(vis,-1,sizeof(vis));
if(dfs(i)) sum++;
}
return sum;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(map,0,sizeof(map));
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++)
{
int a,b;
scanf("%d",&a);
for(int j=0;j
4 3
1 2
1 3
1 4
4 5
1 2
2 3
1 3
1 4
3 4
樣例輸出
No
Yes
#include
#include
int father[1010],ans[1010];
void ini()
{
for(int i=0;i<=1010;i++)
father[i]=i;
}
int find(int x)
{
if(father[x]==x)
return x;
else
return father[x]=find(father[x]);
}
int main()
{
int ncases,n,m,x,y,i,count,jdcount;
scanf("%d",&ncases);
while(ncases--)
{
memset(ans,0,sizeof(ans));
ini();
count=jdcount=0;
scanf("%d %d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d %d",&x,&y);
ans[x]++; ans[y]++;
x=find(x); y=find(y);
if(x!=y)
father[x]=father[y];
}
for(i=1;i<=n;i++)
if(find(i)==i)
count++;//判斷連通性
for(i=1;i<=n;i++)
if(ans[i]%2==1)
jdcount++;//奇點個數
if((jdcount==0||jdcount==2)&&count==1)
printf("Yes\n");
else
printf("No\n");
}
}
#include
#include
#include
int father[1005];
int degree[1005];
int find(int x)
{
if(x!=father[x])
father[x]=find(father[x]);
return father[x];
}
void merge(int x,int y)
{
x=find(x);
y=find(y);
if(x!=y)
father[x]=y;
}
int main()
{
int i,a,b,n,p,q,cnt,dnt;
scanf("%d",&n);
while(n--){
cnt=dnt=0;
memset(degree,0,sizeof(degree));
scanf("%d%d",&p,&q);
for(i=1;i<=p;i++)
father[i]=i;
while(q--){
scanf("%d%d",&a,&b);
if(a==b) continue;
degree[a]++;
degree[b]++;
merge(a,b);
}
for(i=1;i<=p;i++){
if(father[i]==i)
cnt++;
if(degree[i]&1)
dnt++;
}
if(cnt==1&&(dnt==0||dnt==2))
puts("Yes");
else
puts("No");
}
//system("pause");
return 0;
}