n点,m边,一个点s,输入m条边,有单向边和双向边,决定双向边的方向使得和s相连的点最多/最少 题目链接
bfs做法:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5+7;
struct node
{
int u,v,id,next;
}edge[2000000];
int color[maxn];
bool vis[maxn];
int head[maxn],cnt;
void addedge(int u,int v,int id)
{
edge[cnt].u = u;
edge[cnt].v =v;
edge[cnt].id= id;
edge[cnt].next = head[u];
head[u] =cnt++;
}
int bfs1(int u)
{
queue<int>o;
o.push(u);
memset(vis,0,sizeof(vis));
int ans = 0;
vis[u] = true;
ans++;
while(!o.empty())
{
int u = o.front();
o.pop();
for(int i=head[u];~i;i = edge[i].next)
{
int v= edge[i].v;
int id = edge[i].id;
if(vis[v])continue;
if(id!=-1)
{
color[id/2] = (id%2);
//取出时按照0,1,2,3,。。的形式取出
//并对2取余判断双向边的方向
}
o.push(v);
vis[v] = true;
ans++;
}
}
return ans;
}
int bfs2(int u)
{
queue<int>o;
o.push(u);
memset(vis,0,sizeof(vis));
int ans = 0;
ans++;
vis[u] = true;
while(!o.empty())
{
int u = o.front();
o.pop();
for(int i=head[u];~i;i = edge[i].next)
{
int v= edge[i].v;
int id = edge[i].id;
if(vis[v])continue;
if(id!=-1)
{
color[id/2] = 1^(id%2);
continue;
//求最小值时能联通的边一律取反,使其不联通
}
o.push(v);
vis[v] = true;
ans++;
}
}
return ans;
}
int main()
{
int n,m,s;
cnt = 0;
memset(head,-1,sizeof(head));
int pos = 0;
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++)
{
int op,u,v;
scanf("%d%d%d",&op,&u,&v);
if(op==1)
{
addedge(u,v,-1);
}
else
{
addedge(u,v,pos);
addedge(v,u,pos+1);
pos+=2;
}
//存储时按0,1, 2,3...的形式存储
}
int ans1 = bfs1(s);
cout<<ans1<<endl;
for(int i=0;i<pos/2;i++)
{
if(color[i])printf("-");
else printf("+");
}
cout<<endl;
int ans2 = bfs2(s);
cout<<ans2<<endl;
for(int i=0;i<pos/2;i++)
{
if(color[i])printf("-");
else printf("+");
}
return 0;
}
dfs做法:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5e5+7;
typedef pair<int,int> pa;
vector<pa>G[maxn];
int sum;
int vis[maxn],ans[maxn],op[maxn];
int u[maxn],v[maxn];
void dfs1(int u)
{
if(vis[u])return;
vis[u] = 1;
sum++;
for(auto y: G[u])
{
if(op[y.second]==1)
dfs1(y.first);
else if(!ans[y.second])
{
if(v[y.second]==y.first)//双向边的正向
ans[y.second] =1;
else ans[y.second] = 2;
dfs1(y.first);
}
}
}
void dfs2(int u)
{
if(vis[u])return;
vis[u] = 1;
sum++;
for(auto y: G[u])
{
if(op[y.second]==1)
dfs2(y.first);
else if(!ans[y.second])
{
if(v[y.second]==y.first)//双向边的正向
ans[y.second] =2;
else ans[y.second] = 1;
}
}
}
int main()
{
int n,m,s;
scanf("%d%d%d",&n,&m,&s);
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&op[i],&u[i],&v[i]);
G[u[i]].push_back(make_pair(v[i],i));
if(op[i]==2)
G[v[i]].push_back(make_pair(u[i],i));
}
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
sum = 0;
dfs1(s);
cout<<sum<<endl;
for(int i=1; i<=m; i++)
{
if(op[i]==2)
{
if(ans[i]==1)
printf("+");
else
printf("-");
}
}
cout<<endl;
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
sum = 0;
dfs2(s);
cout<<sum<<endl;
for(int i=1; i<=m; i++)
{
if(op[i]==2)
{
if(ans[i]==1)
printf("+");
else
printf("-");
}
}
cout<<endl;
return 0;
}