題目連接:https://vijos.org/p/Victoria%E7%9A%84%E8%88%9E%E4%BC%9A
這是一個圖論的系列題目,題目比較簡單,主要在於數據實在是弱···兩百個點暴搜都能過啊···
vijos用戶體驗還是不錯的 除了管理不太嚴格導致題解混亂 雖然二老闆在但也長期無人打理 如果照管好 這一定會是一個相當出色的OJ
1021 舞會1
這道題目其實就是簡單的統計 不多說 上代碼
//vijos1021 Victoria的舞會1 模擬
//copuright by ametake
#include
using namespace std;
int a[200+10];
int n,k,m;
int main()
{
scanf("%d%d",&n,&k);
int x=0;
for (int i=1;i<=n;i++)
{
while (scanf("%d",&x)&&(x!=0)) a[i]++;
if (a[i]>=k) m++;
}
printf("%d\n",m);
return 0;
}
1022 舞會2
由於交流具有傳遞性 每個小組都是一個儘可能大的環 直接統計強連通分量個數即可
//vijos1022 Victoria的舞會2 tarjan
//copuright by ametake
#include
#include
#include
using namespace std;
const int maxn=200+10;
const int maxm=40000+10;
int n,m=0;
int hd[maxn],tt[maxm*2],nxt[maxm*2],et=0;
int dfn[maxn],low[maxn],sta[maxn],stp=0,dep=0;
bool ins[maxn];
inline int read()
{
int a=0;
char ch=getchar();
while (ch<'0'||ch>'9')
{
ch=getchar();
}
while (ch>='0'&&ch<='9')
{
a=a*10+ch-'0';
ch=getchar();
}
return a;
}
void add(int x,int y)
{
et++;
tt[et]=y;
nxt[et]=hd[x];
hd[x]=et;
}
void tarjan(int x)
{
dfn[x]=low[x]=++dep;
ins[x]=true;
sta[++stp]=x;
for (int i=hd[x];i!=0;i=nxt[i])
{
if (!dfn[tt[i]])
{
tarjan(tt[i]);
low[x]=min(low[x],low[tt[i]]);
}
else if (ins[tt[i]])
{
low[x]=min(low[x],dfn[tt[i]]);
}
}
if (dfn[x]==low[x])
{
int j;
m++;
do
{
j=sta[stp--];
ins[j]=false;
}while (j!=x);
}
return;
}
int main()
{
n=read();
for (int i=1;i<=n;i++)
{
int x=read();
while (x)
{
add(i,x);
x=read();
}
}
for (int i=1;i<=n;i++)
{
if (!dfn[i])
{
tarjan(i);
}
}
printf("%d\n",m);
return 0;
}
1023 舞會3
這道題目做法很多樣 雖然題解裏說數據弱到粘第二題代碼都能過(太坑了吧!難道不存在一條鏈的情況嗎?!)但我還是老實寫了強連通縮點+統計入度
我們考慮什麼樣的情況可以不用通知呢?一個是環,因爲環內人可以互相通知,只需通知一個人就可以了,因此可以縮成一點;另一個是鏈,鏈起始點的人可以通知到這條鏈上所有人。
因此,做一次tarjan之後統計出度爲0的節點就可以了。但不知爲什麼,同樣的方法間諜網絡就T了= =
代碼:
//vijos1023 Victoria的舞會3 tarjan
//copuright by ametake
#include
#include
#include
using namespace std;
const int maxn=200+10;
const int maxm=40000+10;
int n,m=0,ans=0;
int hd[maxn],tt[maxm*2],nxt[maxm*2],et=0;
int dfn[maxn],low[maxn],sta[maxn],stp=0,dep=0;
bool ins[maxn],ru[maxn][maxn];
int inwhich[maxn],rudu[maxn];
inline int read()
{
int a=0;
char ch=getchar();
while (ch<'0'||ch>'9')
{
ch=getchar();
}
while (ch>='0'&&ch<='9')
{
a=a*10+ch-'0';
ch=getchar();
}
return a;
}
void add(int x,int y)
{
et++;
tt[et]=y;
nxt[et]=hd[x];
hd[x]=et;
}
void tarjan(int x)
{
dfn[x]=low[x]=++dep;
ins[x]=true;
sta[++stp]=x;
for (int i=hd[x];i!=0;i=nxt[i])
{
if (!dfn[tt[i]])
{
tarjan(tt[i]);
low[x]=min(low[x],low[tt[i]]);
}
else if (ins[tt[i]])
{
low[x]=min(low[x],dfn[tt[i]]);
}
}
if (dfn[x]==low[x])
{
int j;
m++;
do
{
j=sta[stp--];
ins[j]=false;
inwhich[j]=m;
}while (j!=x);
}
return;
}
int main()
{
n=read();
for (int i=1;i<=n;i++)
{
int x=read();
while (x)
{
add(i,x);
x=read();
}
}
for (int i=1;i<=n;i++)
{
if (!dfn[i])
{
tarjan(i);
}
}
for (int i=1;i<=n;i++)
{
for (int j=hd[i];j!=0;j=nxt[j])
{
if ((inwhich[i]!=inwhich[tt[j]])&&(!ru[inwhich[i]][inwhich[tt[j]]]))
{
ru[inwhich[i]][inwhich[tt[j]]]=true;
rudu[tt[j]]++;
}
}
}
for (int i=1;i<=m;i++) if (rudu[i]==0) ans++;
printf("%d\n",ans);
return 0;
}
——東籬把酒黃昏後,有暗香盈袖