http://zuojie.3322.org:88/soj/problem.action?id=3730
3730: Frenemies
Submit your solution Discuss this problem Best solutions |
Time Limit: 3000 MS Memory Limit: 65536 K
Description
You may have heard the expression "the enemy of my enemy is my friend". By
extension, then, "the enemy of my enemy of my enemy is my enemy", and so on.
Given a set of relationships, you wish to determine how much of a friend or enemy
people are, represented by a "total relationship score".
Input
Input to this problem will begin with a line containing a single integer N (1 ≤
N ≤ 100) indicating the number of data sets. Each data set will consist of a
series of lines.
The first line will contain a single integer P (1 ≤ P ≤ 9) specifying the
number of people in this data set.
The next P lines will contain a relationship matrix that describes direct
relationships between each person in the format "Name R1 R2 ... RX ... RP", with
Name being a unique name for a person consisting of up to twenty contiguous
alphanumeric characters and RX indicating the relationship that exists between
this person and person X, with "F" representing a friend, an "E" representing an
enemy, and "N" representing a neutral relationship. For example, if a line
contained "Bob F E N", this would indicate that Bob is friends with the person on
the first line of the relationship matrix, enemies with the person on the second
line of the relationship matrix, and has a neutral relationship with the person
on the third line of the relationship matrix. Note that a person will always have
a neutral relationship with themselves and that relationships are bi-directional
(e.g., if Bob is a friend with George, then George is a friend with Bob).
The last line in the data set will contain a single name for which the total
relationship scores between that person and every other person are to be
computed.
Output
For each data set, print a single line containing the total relationship scores
between the name given in the final line of the data set and every other person
in the data set, with each score separated by a single space and in the same
order that the names appear in the input. The total relationship score between
two people is the sum total of all the relationship scores of direct and indirect
relationships between them. Direct relationships are determined by the input
described above. Indirect relationships are those in which a cycle-free path of
two or more relationships can be traced between two people, with none of those
relationships being of the neutral variety (e.g., an "enemy of an enemy" or an
"enemy of a friend of an enemy"). The formula for determining a direct or
indirect relationship score is as follows:
where x is the number of enemy relationships in the path and y is the total number
of relationships in the path. Some examples follow:
Also note that the total relationship score of a person with themselves is 0.
Sample Input
3
5
Bob N F E N N
Friend F N N N N
Enemy E N N F E
FriendOfEnemy N N F N N
EnemyOfEnemy N N E N N
Bob
4
Bob N F F F
Tom F N E E
Tim F E N F
Joe F E F N
Bob
4
Spy1 N E F N
Spy2 E N E N
Spy3 F E N N
Spy4 N N N N
Spy3
Sample Output
0 128 -128 -64 64
0 -64 128 128
192 -192 0 0
就是求一点到所有点的经过的路径的权值和
简单的DFS回溯,刚开始还以为是Floyd
后来发现是搜索,数据测试正确,但是一直WA
比赛结束后,发现错在我标记边为已经访问,其实应该标记点为已经访问
很久没做搜索题了,这么简单的错误都犯。故写下此题解警戒。
题解:
对于给点的点对其它每一个点做一次回溯搜索,
访问所有可以从起点到目标点的路径,把权值求和。
#include<cstdio>
#include<cstring>
int n,start,end,map[15][15],score[15],f[15];
void dfs(int x,int s,int p)//x表示当前结点,s表示人数,p表示正负
{
if(x==end)
{
score[end]+=128*p/(1<<(s-1));//128*(-1)^p/2^(s-1)
return;
}
for(int i=0;i<n;i++)
if(!f[x]&&i!=start&&map[x][i])
{
f[x]=1;
dfs(i,s+1,p*map[x][i]);
f[x]=0;
}
}
int main()
{
int t,i,j;
scanf("%d",&t);
while(t--)
{
memset(f,0,sizeof(f));
memset(score,0,sizeof(score));
memset(map,0,sizeof(map));
char s[15][25],str[15],key[25];
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%s",s[i]);
for(j=0;j<n;j++)
{
scanf("%s",str);
map[i][j]=0;
if(str[0]=='F')
map[j][i]=map[i][j]=1;
if(str[0]=='E')
map[j][i]=map[i][j]=-1;
}
}
scanf("%s",key);
start=n;
for(i=0;i<n;i++)
if(!strcmp(key,s[i]))
start=i;
for(end=0;end<n;end++)
if(start!=end)
dfs(start,0,1);
printf("%d",score[0]);
for(i=1;i<n;i++)
printf(" %d",score[i]);
puts("");
}
}